Merge mozilla-central to b2g-inbound

This commit is contained in:
Carsten "Tomcat" Book 2015-09-29 12:43:31 +02:00
Родитель 47191bf610 b63d7b04fc
Коммит 2696da0f1c
522 изменённых файлов: 15209 добавлений и 6901 удалений

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

@ -22,7 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1108782 - Follow-up: clobber. r=me
There's all kinds fail waiting at the end of these dependency changes.
Definitely clobber needed!
Bug 1205242 - Changed toolchain, needs clobber

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

@ -2071,6 +2071,10 @@ DocAccessible::ValidateARIAOwned()
nsIContent* childEl = childEls->ElementAt(idx);
Accessible* child = GetAccessible(childEl);
if (child && child->IsInDocument() && !child->GetFrame()) {
if (!child->Parent()) {
NS_ERROR("An element in the document doesn't have a parent?");
continue;
}
UpdateTreeOnRemoval(child->Parent(), childEl);
}
}

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

@ -225,7 +225,7 @@ child:
prio(high) sync MaxValue(uint64_t aID) returns(double aValue);
prio(high) sync Step(uint64_t aID) returns(double aStep);
prio(high) sync TakeFocus(uint64_t aID);
async TakeFocus(uint64_t aID);
prio(high) sync EmbeddedChildCount(uint64_t aID) returns(uint32_t aCount);
prio(high) sync IndexOfEmbeddedChild(uint64_t aID, uint64_t aChildID)
returns(uint32_t childIdx);

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

@ -1872,6 +1872,9 @@ pref("privacy.trackingprotection.ui.enabled", false);
pref("privacy.trackingprotection.introCount", 0);
pref("privacy.trackingprotection.introURL", "https://www.mozilla.org/%LOCALE%/firefox/%VERSION%/tracking-protection/start/");
// Enable Contextual Identity Containers
pref("privacy.userContext.enabled", false);
#ifndef RELEASE_BUILD
// At the moment, autostart.2 is used, while autostart.1 is unused.
// We leave it here set to false to reset users' defaults and allow

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

@ -11,12 +11,44 @@
style="border:0px;padding:0px;margin:0px;-moz-appearance:none">
<menu id="file-menu" label="&fileMenu.label;"
accesskey="&fileMenu.accesskey;">
<menupopup id="menu_FilePopup">
<menupopup id="menu_FilePopup"
onpopupshowing="updateUserContextUIVisibility();">
<menuitem id="menu_newNavigatorTab"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"
key="key_newNavigatorTab"
accesskey="&tabCmd.accesskey;"/>
<menu id="menu_newUserContext"
label="&newUserContext.label;"
accesskey="&newUserContext.accesskey;"
hidden="true">
<menupopup>
<menuitem id="menu_newUserContextTabPersonal"
usercontextid="1"
class="menuitem-iconic"
label="&userContextPersonal.label;"
command="Browser:NewUserContextTab"
accesskey="&userContextPersonal.accesskey;"/>
<menuitem id="menu_newUserContextTabWork"
usercontextid="2"
class="menuitem-iconic"
label="&userContextWork.label;"
command="Browser:NewUserContextTab"
accesskey="&userContextWork.accesskey;"/>
<menuitem id="menu_newUserContextTabBanking"
usercontextid="3"
class="menuitem-iconic"
label="&userContextBanking.label;"
command="Browser:NewUserContextTab"
accesskey="&userContextBanking.accesskey;"/>
<menuitem id="menu_newUserContextTabShopping"
usercontextid="4"
class="menuitem-iconic"
label="&userContextShopping.label;"
command="Browser:NewUserContextTab"
accesskey="&userContextShopping.accesskey;"/>
</menupopup>
</menu>
<menuitem id="menu_newNavigator"
label="&newNavigatorCmd.label;"
accesskey="&newNavigatorCmd.accesskey;"

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

@ -92,6 +92,7 @@
<command id="cmd_gestureRotateEnd" oncommand="gGestureSupport.rotateEnd()"/>
<command id="Browser:OpenLocation" oncommand="openLocation();"/>
<command id="Browser:RestoreLastSession" oncommand="restoreLastSession();" disabled="true"/>
<command id="Browser:NewUserContextTab" oncommand="openNewUserContextTab(event.sourceEvent);" reserved="true"/>
<command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
<command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>

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

@ -4060,6 +4060,31 @@ function updateEditUIVisibility()
#endif
}
/**
* Opens a new tab with the userContextId specified as an attribute of
* sourceEvent. This attribute is propagated to the top level originAttributes
* living on the tab's docShell.
*
* @param event
* A click event on a userContext File Menu option
*/
function openNewUserContextTab(event)
{
openUILinkIn(BROWSER_NEW_TAB_URL, "tab", {
userContextId: event.target.getAttribute('usercontextid'),
});
}
/**
* Updates File Menu User Context UI visibility depending on
* privacy.userContext.enabled pref state.
*/
function updateUserContextUIVisibility()
{
let userContextEnabled = Services.prefs.getBoolPref("privacy.userContext.enabled");
document.getElementById("menu_newUserContext").hidden = !userContextEnabled;
}
/**
* Makes the Character Encoding menu enabled or disabled as appropriate.
* To be called when the View menu or the app menu is opened.

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

@ -1415,6 +1415,7 @@
var aSkipAnimation;
var aForceNotRemote;
var aNoReferrer;
var aUserContextId;
if (arguments.length == 2 &&
typeof arguments[1] == "object" &&
!(arguments[1] instanceof Ci.nsIURI)) {
@ -1431,6 +1432,7 @@
aSkipAnimation = params.skipAnimation;
aForceNotRemote = params.forceNotRemote;
aNoReferrer = params.noReferrer;
aUserContextId = params.userContextId;
}
var bgLoad = (aLoadInBackground != null) ? aLoadInBackground :
@ -1448,7 +1450,8 @@
skipAnimation: aSkipAnimation,
allowMixedContent: aAllowMixedContent,
forceNotRemote: aForceNotRemote,
noReferrer: aNoReferrer });
noReferrer: aNoReferrer,
userContextId: aUserContextId });
if (!bgLoad)
this.selectedTab = tab;
@ -1690,6 +1693,7 @@
let remote = aParams && aParams.remote;
let uriIsAboutBlank = aParams && aParams.uriIsAboutBlank;
let isPreloadBrowser = aParams && aParams.isPreloadBrowser;
let userContextId = aParams && aParams.userContextId;
let b = document.createElementNS(NS_XUL, "browser");
b.permanentKey = {};
@ -1699,6 +1703,9 @@
b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu"));
b.setAttribute("tooltip", this.getAttribute("contenttooltip"));
if (userContextId)
b.setAttribute("usercontextid", userContextId);
if (remote)
b.setAttribute("remote", "true");
@ -1767,6 +1774,7 @@
var aAllowMixedContent;
var aForceNotRemote;
var aNoReferrer;
var aUserContextId;
if (arguments.length == 2 &&
typeof arguments[1] == "object" &&
!(arguments[1] instanceof Ci.nsIURI)) {
@ -1783,6 +1791,7 @@
aAllowMixedContent = params.allowMixedContent;
aForceNotRemote = params.forceNotRemote;
aNoReferrer = params.noReferrer;
aUserContextId = params.userContextId;
}
// if we're adding tabs, we're past interrupt mode, ditch the owner
@ -1831,16 +1840,18 @@
let b;
let usingPreloadedContent = false;
// If we open a new tab with the newtab URL,
// check if there is a preloaded browser ready.
if (aURI == BROWSER_NEW_TAB_URL) {
// If we open a new tab with the newtab URL in the default
// userContext, check if there is a preloaded browser ready.
if (aURI == BROWSER_NEW_TAB_URL && !aUserContextId) {
b = this._getPreloadedBrowser();
usingPreloadedContent = !!b;
}
if (!b) {
// No preloaded browser found, create one.
b = this._createBrowser({remote, uriIsAboutBlank});
b = this._createBrowser({remote: remote,
uriIsAboutBlank: uriIsAboutBlank,
userContextId: aUserContextId});
}
let notificationbox = this.getNotificationBox(b);
@ -2486,6 +2497,11 @@
if (ourBrowser.isRemoteBrowser != otherBrowser.isRemoteBrowser)
return;
// Keep the userContextId if set on other browser
if (otherBrowser.hasAttribute("usercontextid")) {
ourBrowser.setAttribute("usercontextid", otherBrowser.getAttribute("usercontextid"));
}
// That's gBrowser for the other window, not the tab's browser!
var remoteBrowser = aOtherTab.ownerDocument.defaultView.gBrowser;
var isPending = aOtherTab.hasAttribute("pending");

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

@ -18,6 +18,7 @@ function onTabModalDialogLoaded(node) {
}
}
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
// Listen for the dialog being created
Services.obs.addObserver(onTabModalDialogLoaded, "tabmodal-dialog-loaded", false);

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

@ -2,6 +2,8 @@
const TEST_PAGE = "http://mochi.test:8888/browser/browser/base/content/test/general/file_double_close_tab.html";
var testTab;
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
function waitForDialog(callback) {
function onTabModalDialogLoaded(node) {
Services.obs.removeObserver(onTabModalDialogLoaded, "tabmodal-dialog-loaded");

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

@ -1,5 +1,7 @@
"use strict";
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
const FIRST_TAB = getRootDirectory(gTestPath) + "close_beforeunload_opens_second_tab.html";
const SECOND_TAB = getRootDirectory(gTestPath) + "close_beforeunload.html";

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

@ -1141,7 +1141,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<binding id="urlbar-rich-result-popup" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-rich-result-popup">
<content ignorekeys="true" level="top" consumeoutsideclicks="never"
aria-owns="search-suggestions-notification richlistbox">
aria-owns="richlistbox">
<xul:hbox anonid="search-suggestions-notification"
align="center"
role="alert"

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

@ -173,6 +173,7 @@ function whereToOpenLink( e, ignoreButton, ignoreAlt )
* skipTabAnimation (boolean)
* allowPinnedTabHostChange (boolean)
* allowPopups (boolean)
* userContextId (unsigned int)
*/
function openUILinkIn(url, where, aAllowThirdPartyFixup, aPostData, aReferrerURI) {
var params;
@ -216,6 +217,7 @@ function openLinkIn(url, where, params) {
var aAllowPinnedTabHostChange = !!params.allowPinnedTabHostChange;
var aNoReferrer = params.noReferrer;
var aAllowPopups = !!params.allowPopups;
var aUserContextId = params.userContextId;
if (where == "save") {
if (!aInitiatingDoc) {
@ -357,7 +359,8 @@ function openLinkIn(url, where, params) {
relatedToCurrent: aRelatedToCurrent,
skipAnimation: aSkipTabAnimation,
allowMixedContent: aAllowMixedContent,
noReferrer: aNoReferrer
noReferrer: aNoReferrer,
userContextId: aUserContextId
});
break;
}

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

@ -27,3 +27,6 @@ content/shared/js/views.js
standalone/content/js/standaloneRoomViews.js
standalone/content/js/webapp.js
ui/ui-showcase.js
# Don't need to check the built tree
standalone/dist

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

@ -3,3 +3,4 @@ node_modules
*.pyc
content/config.js
content/VERSION.txt
dist

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

@ -21,6 +21,24 @@ install: npm_install
npm_install:
@npm install
# build the dist dir, which contains a production version of the code and
# assets
.PHONY: dist
dist:
cp -pr content dist
NODE_ENV="production" $(NODE_LOCAL_BIN)/webpack \
-p -v --display-errors
sed 's#webappEntryPoint.js#js/standalone.js#' \
< content/index.html > dist/index.html
.PHONY: distclean
distclean:
rm -fr dist
.PHONY: distserver
distserver: remove_old_config dist
LOOP_CONTENT_DIR=dist node server.js
test:
@echo "Not implemented yet."

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

@ -18,15 +18,37 @@
<link rel="localization" href="l10n/{locale}/loop.properties">
<script>
(function() {
function insertScript(url) {
var node = document.createElement("script");
var sibling = document.getElementsByTagName("script")[0];
node.async = 1;
node.src = url;
sibling.parentNode.insertBefore(node, sibling);
}
function insertScript(url, sync) {
var node = document.createElement("script");
var sibling = document.getElementsByTagName("script")[0];
node.async = !sync;
node.src = url;
sibling.parentNode.insertBefore(node, sibling);
}
/**
* Synchronously load the supplied script into the DOM (using <script>).
* Eventually, we probably want to do a full build step even for
* development, after which this can go away.
*
* Instead of having to specify the scripts we need here, and in
* some webpack config file for bundling, we specify them in
* webappEntryPoint.js, which require()s them. Webpack handles that
* during bundling, but for the current dev-server setup, where we don't
* (yet) have a full build step, we need to provide a require() function.
*
* @param webpackUrl - a URL, possibly preceded by webpack loader syntax.
* webpack loader syntax is stripped off
*
*/
function require(url) {
var devTimeUrl = url.replace(/^script!/, '');
var devTimeUrl = devTimeUrl.replace(/^imports.*!/, '');
var devTimeUrl = devTimeUrl.replace(/^exports.*!/, '');
insertScript(devTimeUrl, true);
}
(function() {
// window.navigator.doNotTrack "yes" is for old versions of FF
// window.navigator.doNotTrack "1" is for current versions of FF + Chrome + Opera
// window.doNotTrack is Safari + IE11
@ -120,34 +142,11 @@
// We don't use the SDK's CSS. This will prevent spurious 404 errors.
window.OTProperties.cssURL = "about:blank";
</script>
<script type="text/javascript" src="shared/libs/sdk.js"></script>
<script type="text/javascript" src="libs/l10n-gaia-02ca67948fe8.js"></script>
<script type="text/javascript" src="shared/libs/react-0.12.2.js"></script>
<script type="text/javascript" src="shared/libs/lodash-3.9.3.js"></script>
<script type="text/javascript" src="shared/libs/backbone-1.2.1.js"></script>
<!-- app scripts -->
<script type="text/javascript" src="config.js"></script>
<script type="text/javascript" src="shared/js/utils.js"></script>
<script type="text/javascript" src="shared/js/crypto.js"></script>
<script type="text/javascript" src="shared/js/mixins.js"></script>
<script type="text/javascript" src="shared/js/actions.js"></script>
<script type="text/javascript" src="shared/js/validate.js"></script>
<script type="text/javascript" src="shared/js/dispatcher.js"></script>
<script type="text/javascript" src="shared/js/websocket.js"></script>
<script type="text/javascript" src="shared/js/otSdkDriver.js"></script>
<script type="text/javascript" src="shared/js/store.js"></script>
<script type="text/javascript" src="shared/js/activeRoomStore.js"></script>
<script type="text/javascript" src="shared/js/views.js"></script>
<script type="text/javascript" src="shared/js/textChatStore.js"></script>
<script type="text/javascript" src="shared/js/textChatView.js"></script>
<script type="text/javascript" src="shared/js/urlRegExps.js"></script>
<script type="text/javascript" src="shared/js/linkifiedTextView.js"></script>
<script type="text/javascript" src="js/standaloneAppStore.js"></script>
<script type="text/javascript" src="js/standaloneMozLoop.js"></script>
<script type="text/javascript" src="js/standaloneRoomViews.js"></script>
<script type="text/javascript" src="js/standaloneMetricsStore.js"></script>
<script type="text/javascript" src="js/webapp.js"></script>
<!-- note that for 'make dist', webappEntryPoint.js is replaced by -->
<!-- the standalone.js bundle -->
<script type="text/javascript" src="webappEntryPoint.js"></script>
<script>
// Wait for all the localization notes to load

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

@ -0,0 +1,57 @@
// When processed by webpack, this file bundles up all the JS for the
// standalone client.
//
// When loaded by the development server, index.html supplies a require
// function to load these.
// Right now, these are manually ordered so that all dependencies are
// satisfied. Before long, we'd like to convert these into real modules
// and/or better shims, and push the dependencies down into the modules
// themselves so that this manual management step goes away.
// To get started, we're using webpack's script loader to load these things in
// as-is.
/* global require */
// The OpenTok SDK tries to do some heuristic detection of require and
// assumes a node environment if it's present, which confuses webpack, so
// we turn that off by forcing require to false in that context.
require("imports?require=>false!shared/libs/sdk.js");
require("script!./libs/l10n-gaia-02ca67948fe8.js");
// Ultimately, we'll likely want to pull the vendor libraries from npm, as that
// makes upgrading easier, and it's generally better practice to minify the
// "source" versions of libraries rather than built artifacts. We probably do
// want to minify them ourselves since this allows for better dead-code
// elimination, but that can be a bit of judgement call.
require("exports?_!shared/libs/lodash-3.9.3.js");
// Note that anything that uses the script loader doesn't get minified, so
// these need to be shimmed to use to other loaders (easiest first cut) or
// turned into real modules:
require("script!shared/libs/backbone-1.2.1.js");
require("script!shared/libs/react-0.12.2.js");
require("script!shared/js/utils.js");
require("script!shared/js/crypto.js");
require("script!shared/js/mixins.js");
require("script!shared/js/actions.js");
require("script!shared/js/validate.js");
require("script!shared/js/dispatcher.js");
require("script!shared/js/websocket.js");
require("script!shared/js/otSdkDriver.js");
require("script!shared/js/store.js");
require("script!shared/js/activeRoomStore.js");
require("script!shared/js/views.js");
require("script!shared/js/urlRegExps.js");
require("script!shared/js/textChatStore.js");
require("script!shared/js/textChatView.js");
require("script!shared/js/linkifiedTextView.js");
require("script!./js/standaloneAppStore.js");
require("script!./js/standaloneMozLoop.js");
require("script!./js/standaloneRoomViews.js");
require("script!./js/standaloneMetricsStore.js");
require("script!./js/webapp.js");

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

@ -12,9 +12,14 @@
},
"dependencies": {},
"devDependencies": {
"compression": "1.5.x",
"eslint": "1.2.x",
"eslint-plugin-react": "3.2.x",
"express": "4.x"
"exports-loader": "0.6.x",
"express": "4.x",
"imports-loader": "0.6.x",
"script-loader": "0.6.x",
"webpack": "1.12.x"
},
"scripts": {
"test": "make test",

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

@ -12,6 +12,11 @@
var express = require("express");
var app = express();
// make dev-server performance more similar to the production server by using
// gzip compression
var compression = require("compression");
app.use(compression());
var path = require("path");
var port = process.env.PORT || 3000;
@ -20,6 +25,10 @@ var feedbackApiUrl = process.env.LOOP_FEEDBACK_API_URL ||
var feedbackProductName = process.env.LOOP_FEEDBACK_PRODUCT_NAME || "Loop";
var loopServerUrl = process.env.LOOP_SERVER_URL || "http://localhost:5000";
// This is typically overridden with "dist" so that it's possible to test the
// optimized version, once it's been built to the "dist" directory
var standaloneContentDir = process.env.LOOP_CONTENT_DIR || "content";
// Remove trailing slashes as double slashes in the url can confuse the server
// responses.
if (loopServerUrl[loopServerUrl.length - 1] === "/") {
@ -70,10 +79,11 @@ app.use("/standalone/content", express.static(path.join(__dirname, "content")));
// does what we need for running in the github loop-client context, the second one
// handles running in the hg repo under mozilla-central and is used so that the shared
// files are in the right location.
app.use("/content", express.static(path.join(__dirname, "content")));
app.use("/content", express.static(path.join(__dirname, standaloneContentDir)));
app.use("/content", express.static(path.join(__dirname, "..", "content")));
// These two are based on the above, but handle call urls, that have a /c/ in them.
app.use("/content/c", express.static(path.join(__dirname, "content")));
app.use("/content/c", express.static(path.join(__dirname,
standaloneContentDir)));
app.use("/content/c", express.static(path.join(__dirname, "..", "content")));
// Two lines for the same reason as /content above.
@ -85,7 +95,7 @@ app.use("/test", express.static(path.join(__dirname, "..", "test")));
function serveIndex(req, res) {
"use strict";
return res.sendfile(path.join(__dirname, "content", "index.html"));
return res.sendFile(path.join(__dirname, standaloneContentDir, "index.html"));
}
app.get(/^\/content\/[\w\-]+$/, serveIndex);

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

@ -0,0 +1,74 @@
/* eslint-env node */
// Webpack hurts to debug (lots of trial-and-error), so put non-trivial
// functionality in other script logic whenever practical.
var path = require("path");
var webpack = require("webpack");
function getSharedDir() {
"use strict";
var fs = require("fs");
// relative path to the shared directory in m-c
var mozillaCentralShared =
path.resolve(path.join(__dirname, "..", "content", "shared"));
try {
// if this doesn't blow up...
fs.statSync(mozillaCentralShared);
// that directory is there, so return it
return mozillaCentralShared;
} catch (ex) {
// otherwise, assume that we're in loop-client, where the shared
// directory is in the content directory
return path.join(__dirname, "content", "shared");
}
}
/**
* See http://webpack.github.io/docs/configuration.html on how this works.
* Make generous use of a search engine and stack overflow to interpret
* those docs.
*/
module.exports = {
entry: "./content/webappEntryPoint.js",
// We want the shared modules to be available without the requirer needing
// to know the path to them, especially that path is different in
// mozilla-central and loop-client.
resolve: {
alias: {
shared: getSharedDir()
}
},
output: {
filename: "standalone.js",
path: path.join(__dirname, "dist", "js"),
// Reduce false-positive warnings when viewing in editors which read
// our eslint config files (which disallows tabs).
sourcePrefix: " "
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
// XXX I'd _like_ to only suppress the warnings for vendor code, since
// we're not likely to fix those. However, since:
//
// * this seems to be hard
// * the consensus seems to be that these warnings are
// aren't terribly high value
// * training people to ignore warnings is pretty much always a bad
// plan
//
// we suppress them everywhere
warnings: false
}
})
]
};

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

@ -6,6 +6,8 @@
const TEST_URL = 'data:text/html,<script>window.onbeforeunload=' +
'function(e){e.returnValue="?"}</script>';
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
function test() {
waitForExplicitFinish();
showTabView(onTabViewShown);

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

@ -15,6 +15,8 @@ const TEST_URL = 'data:text/html,<script>window.onbeforeunload=' +
var contentWindow;
var activeGroup;
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
Components.utils.import("resource://gre/modules/Promise.jsm", this);
function test() {

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

@ -1,10 +1,10 @@
[
{
"clang_version": "r241406"
"clang_version": "r247539"
},
{
"size": 100307285,
"digest": "4d147d0072a928945fc1e938f39a5d0a9d3c676399c09e092c8750b2f973cdbbebda8d94d4d05805fae74a5c49c54263dc22b8b443c23c9a0ae830a261d3cf30",
"size": 93197192,
"digest": "6ebd8994ac76cf6694c3d9054104219836f47578223c799cb9ba9669cfdee00112e9de56aea9d1e6d9d50ee94a201970555de19794b5fbb7546f58fdf8e59a99",
"algorithm": "sha512",
"filename": "clang.tar.bz2",
"unpack": true,

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

@ -1,10 +1,10 @@
[
{
"clang_version": "r241406"
"clang_version": "r247539"
},
{
"size": 83297360,
"digest": "18e3deaf608b58a9153d647e1acbe6e93b7d6461bd4f86f24d13f4b6818b048a65063200d7acb100fa41eb5a7e66dfe6bdc89770c15c87e32a3e9a50d97094c6",
"size": 93197192,
"digest": "6ebd8994ac76cf6694c3d9054104219836f47578223c799cb9ba9669cfdee00112e9de56aea9d1e6d9d50ee94a201970555de19794b5fbb7546f58fdf8e59a99",
"algorithm": "sha512",
"filename": "clang.tar.xz",
"unpack": true

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

@ -1,10 +1,10 @@
[
{
"clang_version": "r241406"
},
"clang_version": "r247539"
},
{
"size": 83297360,
"digest": "18e3deaf608b58a9153d647e1acbe6e93b7d6461bd4f86f24d13f4b6818b048a65063200d7acb100fa41eb5a7e66dfe6bdc89770c15c87e32a3e9a50d97094c6",
"size": 93197192,
"digest": "6ebd8994ac76cf6694c3d9054104219836f47578223c799cb9ba9669cfdee00112e9de56aea9d1e6d9d50ee94a201970555de19794b5fbb7546f58fdf8e59a99",
"algorithm": "sha512",
"filename": "clang.tar.xz",
"unpack": true

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

@ -1,12 +1,12 @@
[
{
"clang_version": "r241406"
},
"clang_version": "r247539"
},
{
"size": 86465808,
"digest": "947eaaf11ac8cbe12e11b48c8b052721e018d31fb8ce20f8bf14b117b6623c56513b1422d8d9c8011bc0b0b985ef74d8f181e7200c6d7a05d79a1bce0d75ddee",
"algorithm": "sha512",
"filename": "clang.tar.bz2",
"size": 97314461,
"digest": "9a74670fa917f760a4767923485d5166bbd258a8023c8aeb899b8c4d22f2847be76508ac5f26d7d2193318a2bb368a71bc62888d1bfe9d81eb45329a60451aa4",
"algorithm": "sha512",
"filename": "clang.tar.xz",
"unpack": true
},
{

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

@ -1,19 +1,12 @@
[
{
"clang_version": "r241406"
"clang_version": "r247539"
},
{
"size": 100307285,
"digest": "4d147d0072a928945fc1e938f39a5d0a9d3c676399c09e092c8750b2f973cdbbebda8d94d4d05805fae74a5c49c54263dc22b8b443c23c9a0ae830a261d3cf30",
"algorithm": "sha512",
"filename": "clang.tar.bz2",
"unpack": true
},
{
"size": 80458572,
"digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"size": 93197192,
"digest": "6ebd8994ac76cf6694c3d9054104219836f47578223c799cb9ba9669cfdee00112e9de56aea9d1e6d9d50ee94a201970555de19794b5fbb7546f58fdf8e59a99",
"algorithm": "sha512",
"filename": "clang.tar.xz",
"unpack": true
},
{

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

@ -308,6 +308,16 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY fileMenu.label "File">
<!ENTITY fileMenu.accesskey "F">
<!ENTITY newUserContext.label "New Container Tab">
<!ENTITY newUserContext.accesskey "C">
<!ENTITY userContextPersonal.label "Personal">
<!ENTITY userContextPersonal.accesskey "P">
<!ENTITY userContextWork.label "Work">
<!ENTITY userContextWork.accesskey "W">
<!ENTITY userContextBanking.label "Banking">
<!ENTITY userContextBanking.accesskey "B">
<!ENTITY userContextShopping.label "Shopping">
<!ENTITY userContextShopping.accesskey "S">
<!ENTITY newNavigatorCmd.label "New Window">
<!ENTITY newNavigatorCmd.key "N">
<!ENTITY newNavigatorCmd.accesskey "N">

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

@ -152,8 +152,15 @@
locale/browser/syncQuota.properties (%chrome/browser/syncQuota.properties)
#endif
% resource search-plugins chrome://browser/locale/searchplugins/
# little trick to make the test below work
#define en_US en-US
#if AB_CD == en_US
locale/browser/searchplugins/list.txt (%searchplugins/list.txt)
locale/browser/searchplugins/ (%searchplugins/*.xml)
#else
locale/browser/searchplugins/list.txt (.deps/generated_@AB_CD@/list.txt)
locale/browser/searchplugins/ (.deps/generated_@AB_CD@/*.xml)
#endif
% locale browser-region @AB_CD@ %locale/browser-region/
locale/browser-region/region.properties (%chrome/browser-region/region.properties)
# the following files are browser-specific overrides

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

@ -166,7 +166,7 @@ PluginContent.prototype = {
pluginName = BrowserUtils.makeNicePluginName(pluginTag.name);
// Convert this from nsIPluginTag so it can be serialized.
let properties = ["name", "description", "filename", "version", "enabledState"];
let properties = ["name", "description", "filename", "version", "enabledState", "niceName"];
let pluginTagCopy = {};
for (let prop of properties) {
pluginTagCopy[prop] = pluginTag[prop];
@ -422,6 +422,7 @@ PluginContent.prototype = {
break;
case "PluginInstantiated":
Services.telemetry.getKeyedHistogramById('PLUGIN_ACTIVATION_COUNT').add(this._getPluginInfo(plugin).pluginTag.niceName);
shouldShowNotification = true;
break;
}

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

@ -1969,3 +1969,5 @@ chatbox {
.browser-action-panel > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
}
%include ../shared/usercontext/usercontext.inc.css

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

@ -142,6 +142,10 @@ browser.jar:
skin/classic/browser/tabview/stack-expander.png (tabview/stack-expander.png)
skin/classic/browser/tabview/tabview.png (tabview/tabview.png)
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
skin/classic/browser/usercontext/personal.svg (../shared/usercontext/personal.svg)
skin/classic/browser/usercontext/work.svg (../shared/usercontext/work.svg)
skin/classic/browser/usercontext/banking.svg (../shared/usercontext/banking.svg)
skin/classic/browser/usercontext/shopping.svg (../shared/usercontext/shopping.svg)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16.png
skin/classic/browser/sync-32.png

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

@ -3655,3 +3655,5 @@ window > chatbox {
.browser-action-panel > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
}
%include ../shared/usercontext/usercontext.inc.css

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

@ -229,6 +229,10 @@ browser.jar:
skin/classic/browser/tabview/stack-expander.png (tabview/stack-expander.png)
skin/classic/browser/tabview/tabview.png (tabview/tabview.png)
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
skin/classic/browser/usercontext/personal.svg (../shared/usercontext/personal.svg)
skin/classic/browser/usercontext/work.svg (../shared/usercontext/work.svg)
skin/classic/browser/usercontext/banking.svg (../shared/usercontext/banking.svg)
skin/classic/browser/usercontext/shopping.svg (../shared/usercontext/shopping.svg)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16.png
skin/classic/browser/sync-32.png

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

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="32" height="32" viewBox="0 0 32 32">
<path fill="#7dc14c" d="M17.3857868,14.0527919 C14.2304569,13.0862944 13.4913706,12.4609137 13.4913706,11.0964467 C13.4913706,9.61827411 14.7137056,8.85076142 16.4192893,8.85076142 C17.9827411,8.85076142 19.3187817,9.33401015 20.5979695,10.4994924 L22.4456853,8.42436548 C21.1664975,7.20203046 19.3187819,6.26535905 17,6.00952148 L17,2 L15,2 L15,6.00952148 C12.3827412,6.43591742 9.76751269,8.53807107 9.76751269,11.3238579 C9.76751269,14.1664975 11.4730964,15.786802 15.4812183,17.0091371 C18.4375635,17.9187817 19.2335025,18.6294416 19.2335025,20.2213198 C19.2335025,22.0690355 17.7553299,23.035533 15.7370558,23.035533 C13.7756345,23.035533 12.2406091,22.3248731 10.9329949,21.1025381 L9,23.2345178 C10.4213198,24.6274112 12.8659899,25.8324934 15,26.0030518 L15,30 L17,30 L17,26.0030518 C20.7116753,25.4060974 22.9857868,22.893401 22.9857868,20.022335 C22.9857868,16.4690355 20.7116751,15.1045685 17.3857868,14.0527919 Z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

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

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="32" height="32" viewBox="0 0 32 32">
<path fill="#00a7e0" d="M7.17741905,12 C7.10965537,12 7.041327,11.9953181 6.97243393,11.985018 C6.33263187,11.8918489 5.90515601,11.3862071 6.01809547,10.8552833 C7.41798011,4.26321358 12.2613889,2.57493207 15.0238882,2.15590491 C19.6448063,1.45690206 24.3408291,3.21541158 25.8344535,5.29743816 C26.1664955,5.76047488 25.9835336,6.35881757 25.4244832,6.63364321 C24.8654329,6.9098734 24.1437497,6.75583996 23.8122724,6.29327142 C22.8923805,5.01043967 19.1749781,3.51130562 15.4479759,4.07406612 C12.8080159,4.474834 9.43056132,6.03623689 8.33561323,11.1942506 C8.23453242,11.666651 7.73816348,12 7.17741905,12 Z M16.63127,26 C16.1452186,26 15.6509104,25.9658335 15.147795,25.8938767 C10.637921,25.257137 6.71207921,21.8114952 6.01575422,17.8807924 C5.91171832,17.2932317 6.33391695,16.7382846 6.95813239,16.6404441 C7.58454965,16.5343208 8.17298555,16.9406954 8.27757192,17.5272206 C8.80876054,20.5255916 11.9766264,23.26409 15.4885263,23.7610576 C17.3975027,24.02766 20.959494,23.8221432 23.3220449,19.3789425 C24.4625867,17.2331815 23.0049831,11.881462 19.9521622,9.34692739 C18.2380468,7.92384005 16.4573263,7.76905536 14.6628445,8.89499751 C13.26469,9.77142052 11.8070864,12.2857658 11.8665355,14.6287608 C11.9127737,16.4835887 12.8386382,17.9325598 14.6171568,18.9363308 C15.2210054,19.2764429 16.9411759,19.4933486 17.9424527,18.8296898 C18.7257495,18.3104622 18.9591422,17.2761485 18.6365758,15.7583267 C18.3822659,14.5650869 17.2219077,12.4452096 16.6664991,12.3711821 C16.6692513,12.3722175 16.4666841,12.4312324 16.1276041,12.9095636 C15.8545786,13.2936782 15.58981,14.7297074 15.9476054,15.3581643 C16.0142104,15.4761941 16.0725586,15.5465978 16.3202632,15.5465978 C16.9532859,15.5465978 17.46686,16.0290705 17.46686,16.6249139 C17.46686,17.2207573 16.9543868,17.7042653 16.3213641,17.7042653 C15.2644914,17.7042653 14.4140391,17.2336992 13.9268868,16.3774655 C13.1083609,14.9388479 13.5536787,12.6548678 14.2202791,11.7137354 C15.2540327,10.2564816 16.3631986,10.1151564 17.1123672,10.2564816 C19.7066595,10.7389543 20.8763754,15.2908666 20.8857331,15.3359043 C21.5303153,18.3648181 20.3594985,19.8665919 19.264094,20.593407 C17.4151172,21.8192603 14.6920186,21.493643 13.4380832,20.7859819 C10.3280151,19.0310652 9.62013053,16.497566 9.5744428,14.6805283 C9.49022326,11.3643051 11.4779146,8.30018945 13.391845,7.10021984 C16.0417332,5.43848454 18.9877658,5.66781436 21.4714167,7.72919442 C25.1176276,10.7565552 27.0871539,17.1229168 25.3746898,20.3433702 C23.4326862,23.9950465 20.2983981,26 16.63127,26 Z M16.0845157,30 C14.9348455,30 13.9050564,29.8557557 13.0394288,29.6610017 C10.2114238,29.0257442 7.58700058,27.4599412 6.18892823,25.5735955 C5.84440518,25.1078371 5.98426642,24.4803503 6.50105099,24.1700066 C7.01675554,23.8596629 7.71552172,23.986423 8.06112477,24.4507244 C9.89498097,26.9252176 15.9397944,29.9781448 22.2508301,26.1937972 C22.7676147,25.8844249 23.4658409,26.0087566 23.8109039,26.474515 C24.155427,26.9397877 24.0161057,27.5672745 23.4993212,27.8776182 C20.7987573,29.4963593 18.2315746,30 16.0845157,30 Z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 3.3 KiB

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

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="32" height="32" viewBox="0 0 32 32">
<path fill="#ee5195" fill-rule="evenodd" d="M20.8195396,14 L15.1804604,14 L15.1804604,14 L15.8471271,18 L20.1528729,18 L20.8195396,14 Z M22.8471271,14 L27.6125741,14 L27.6125741,14 L26.2792408,18 L22.1804604,18 L22.8471271,14 Z M21.1528729,12 L14.8471271,12 L14.8471271,12 L14.1804604,8 L21.8195396,8 L21.1528729,12 Z M23.1804604,12 L28.2792408,12 L28.2792408,12 L29.6125741,8 L23.8471271,8 L23.1804604,12 Z M13.1528729,14 L8.47703296,14 L10.077033,18 L10.077033,18 L13.8195396,18 L13.1528729,14 Z M12.8195396,12 L7.67703296,12 L6.07703296,8 L12.1528729,8 L12.8195396,12 L12.8195396,12 Z M31.7207592,8 L32,8 L32,6 L31,6 L5.27703296,6 L5.27703296,6 L4,2.8074176 L4,2 L3,2 L1,2 L0,2 L0,4 L1,4 L2.32296704,4 L9.78931928,22.6658806 L9.78931928,22.6658806 C8.71085924,23.3823847 8,24.6081773 8,26 C8,28.209139 9.790861,30 12,30 C14.209139,30 16,28.209139 16,26 C16,25.2714257 15.8052114,24.5883467 15.4648712,24 L22.5351288,24 C22.1947886,24.5883467 22,25.2714257 22,26 C22,28.209139 23.790861,30 26,30 C28.209139,30 30,28.209139 30,26 C30,23.790861 28.209139,22 26,22 L11.677033,22 L10.877033,20 L27,20 L28,20 L28,19.1622777 L31.7207592,8 L31.7207592,8 Z M26,28 C27.1045695,28 28,27.1045695 28,26 C28,24.8954305 27.1045695,24 26,24 C24.8954305,24 24,24.8954305 24,26 C24,27.1045695 24.8954305,28 26,28 Z M12,28 C13.1045695,28 14,27.1045695 14,26 C14,24.8954305 13.1045695,24 12,24 C10.8954305,24 10,24.8954305 10,26 C10,27.1045695 10.8954305,28 12,28 Z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 1.8 KiB

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

@ -0,0 +1,17 @@
/* User Context UI browser styles */
#menu_newUserContextTabPersonal {
list-style-image: url("chrome://browser/skin/usercontext/personal.svg");
}
#menu_newUserContextTabWork {
list-style-image: url("chrome://browser/skin/usercontext/work.svg");
}
#menu_newUserContextTabBanking {
list-style-image: url("chrome://browser/skin/usercontext/banking.svg");
}
#menu_newUserContextTabShopping {
list-style-image: url("chrome://browser/skin/usercontext/shopping.svg");
}

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

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg"
width="32" height="32" viewBox="0 0 32 32">
<path fill="#f89c24" fill-rule="evenodd" d="M22,9.99887085 L21.635468,10 L29.0034652,10 C29.5538362,10 30,10.4449463 30,10.9933977 L30,27.0066023 C30,27.5552407 29.5601869,28 29.0034652,28 L2.99653482,28 C2.44616384,28 2,27.5550537 2,27.0066023 L2,10.9933977 C2,10.4447593 2.43981314,10 2.99653482,10 L8,10 L8,7.99922997 C8,5.79051625 10.0426627,4 12.5635454,4 L19.4364546,4 C21.9568311,4 24,5.79246765 24,7.99922997 L24,9.99267578 L22,9.99887085 L22,10 L10,10 L10,7.99922997 C10,6.89421235 11.0713286,6 12.3917227,6 L19.6082773,6 C20.9273761,6 22,6.89552665 22,7.99922997 L22,9.99887085 Z"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 941 B

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

@ -2842,3 +2842,5 @@ chatbox {
.browser-action-panel > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
}
%include ../shared/usercontext/usercontext.inc.css

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

@ -254,6 +254,10 @@ browser.jar:
skin/classic/browser/tabview/tabview.png (tabview/tabview.png)
skin/classic/browser/tabview/tabview-inverted.png (tabview/tabview-inverted.png)
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
skin/classic/browser/usercontext/personal.svg (../shared/usercontext/personal.svg)
skin/classic/browser/usercontext/work.svg (../shared/usercontext/work.svg)
skin/classic/browser/usercontext/banking.svg (../shared/usercontext/banking.svg)
skin/classic/browser/usercontext/shopping.svg (../shared/usercontext/shopping.svg)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16.png
skin/classic/browser/sync-32.png

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

@ -39,7 +39,7 @@ if test -n "$ENABLE_CLANG_PLUGIN"; then
LLVM_LDFLAGS=`$LLVMCONFIG --system-libs | xargs`
LLVM_LDFLAGS="$LLVM_LDFLAGS `$LLVMCONFIG --ldflags --libs core mc analysis asmparser mcparser bitreader option | xargs`"
if test "${OS_ARCH}" = "Darwin"; then
if test "${HOST_OS_ARCH}" = "Darwin"; then
CLANG_LDFLAGS="-lclangFrontend -lclangDriver -lclangSerialization"
CLANG_LDFLAGS="$CLANG_LDFLAGS -lclangParse -lclangSema -lclangAnalysis"
CLANG_LDFLAGS="$CLANG_LDFLAGS -lclangEdit -lclangAST -lclangLex"

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

@ -222,3 +222,15 @@ MOZ_RUN_CONFIG_STATUS()],
define([AC_CONFIG_HEADER],
[m4_fatal([Use CONFIGURE_DEFINE_FILES in moz.build files to produce header files.])
])
define([MOZ_BUILD_BACKEND],
[
BUILD_BACKENDS="RecursiveMake"
MOZ_ARG_ENABLE_STRING(build-backend,
[ --enable-build-backend={AndroidEclipse,CppEclipse,VisualStudio,FasterMake,CompileDB}
Enable additional build backends],
[ BUILD_BACKENDS="RecursiveMake `echo $enableval | sed 's/,/ /g'`"])
AC_SUBST_LIST([BUILD_BACKENDS])
])

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

@ -14,6 +14,17 @@ OS_COMPILE_CXXFLAGS :=
OS_LDFLAGS := $(LLVM_LDFLAGS) $(CLANG_LDFLAGS)
DSO_LDOPTS := -shared
ifeq ($(HOST_OS_ARCH)_$(OS_ARCH),Linux_Darwin)
# Use the host compiler instead of the target compiler.
CXX := $(HOST_CXX)
# expandlibs doesn't know the distinction between host and target toolchains,
# and on cross linux/darwin builds, the options to give to the linker for file
# lists differ between both, so don't use file lists.
EXPAND_MKSHLIB_ARGS :=
# Don't pass OSX linker arguments.
MOZ_FIX_LINK_PATHS :=
endif
# Use the default OS X deployment target to enable using the libc++ headers
# correctly. Note that the binary produced here is a host tool and doesn't need
# to be distributed.

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

@ -13,6 +13,11 @@ SOURCES += [
DISABLE_STL_WRAPPING = True
NO_VISIBILITY_FLAGS = True
# libc++ is required to build plugins against clang on OS X.
if CONFIG['HOST_OS_ARCH'] == 'Darwin':
CXXFLAGS += ['-stdlib=libc++']
LDFLAGS += ['-lc++']
DIRS += [
'tests',
]

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

@ -131,6 +131,7 @@ MACH_MODULES = [
'python/mozbuild/mozbuild/mach_commands.py',
'python/mozbuild/mozbuild/backend/mach_commands.py',
'python/mozbuild/mozbuild/compilation/codecomplete.py',
'python/mozbuild/mozbuild/compilation/database.py',
'python/mozbuild/mozbuild/frontend/mach_commands.py',
'services/common/tests/mach_commands.py',
'testing/luciddream/mach_commands.py',

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

@ -38,10 +38,9 @@ export OTOOL=${TOOLCHAIN_PREFIX}otool
export GENISOIMAGE=$topsrcdir/genisoimage/genisoimage
export DMG_TOOL=$topsrcdir/dmg/dmg
# The system gcc installed on CentOS 6 is 4.4, which our
# build system rejects.
export HOST_CC="$topsrcdir/gcc/bin/gcc"
export HOST_CXX="$topsrcdir/gcc/bin/g++"
export HOST_CC="$topsrcdir/clang/bin/clang"
export HOST_CXX="$topsrcdir/clang/bin/clang++"
export HOST_CPP="$topsrcdir/clang/bin/clang -E"
export HOST_LDFLAGS="-g"
ac_add_options --target=x86_64-apple-darwin

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

@ -1,5 +1,5 @@
{
"llvm_revision": "241406",
"llvm_revision": "247539",
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/trunk",
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/trunk",
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk",

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

@ -45,7 +45,9 @@ ifndef JS_STANDALONE
ifndef MOZ_PROFILE_USE
# Generate a new buildid every time we "export" in config... that's only
# supposed to be once per-build!
export::
export:: buildid
buildid: FORCE
ifdef MOZ_BUILD_DATE
printf '%s' $(MOZ_BUILD_DATE) > buildid
else

209
config/faster/rules.mk Normal file
Просмотреть файл

@ -0,0 +1,209 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# /!\ Please make sure to update the following comment when you touch this
# file. Thank you /!\
# The traditional Mozilla build system relied on going through the entire
# build tree a number of times with different targets, and many of the
# things happening at each step required other things happening in previous
# steps without any documentation of those dependencies.
#
# This new build system tries to start afresh by establishing what files or
# operations are needed for the build, and applying the necessary rules to
# have those in place, relying on make dependencies to get them going.
#
# As of writing, only building non-compiled parts of Firefox is supported
# here (a few other things are also left out). This is a starting point, with
# the intent to grow this build system to make it more complete.
#
# This file contains rules and dependencies to get things working. The intent
# is for a Makefile to define some dependencies and variables, and include
# this file. What needs to be defined there, and ends up being generated by
# python/mozbuild/mozbuild/backend/fastermake.py is the following:
# - TOPSRCDIR/TOPOBJDIR, respectively the top source directory and the top
# object directory
# - PYTHON, the path to the python executable
# - ACDEFINES, which contains a set of -Dvar=name to be used during
# preprocessing
# - MOZ_CHROME_FILE_FORMAT, which defines whether to use file copies or
# symbolic links
# - JAR_MN_TARGETS, which defines the targets to use for jar manifest
# processing, see further below
# - PP_TARGETS, which defines the file paths of preprocessed files, see
# further below
# - INSTALL_MANIFESTS, which defines the list of base directories handled
# by install manifests, see further below
# - MANIFEST_TARGETS, which defines the file paths of chrome manifests, see
# further below
#
# A convention used between this file and the Makefile including it is that
# global Make variables names are uppercase, while "local" Make variables
# applied to specific targets are lowercase.
# Targets to be triggered for a default build
default: $(addprefix install-,$(INSTALL_MANIFESTS))
default: $(addprefix jar-,$(JAR_MN_TARGETS))
# Explicit files to be built for a default build
default: $(addprefix $(TOPOBJDIR)/,$(PP_TARGETS))
default: $(addprefix $(TOPOBJDIR)/,$(MANIFEST_TARGETS))
default: $(TOPOBJDIR)/dist/bin/greprefs.js
default: $(TOPOBJDIR)/dist/bin/platform.ini
default: $(TOPOBJDIR)/dist/bin/webapprt/webapprt.ini
.PHONY: FORCE
# Extra define to trigger some workarounds. We should strive to limit the
# use of those. As of writing the only one is in
# toolkit/content/buildconfig.html.
ACDEFINES += -DBUILD_FASTER
# Generic rule to fall back to the recursive make backend
$(TOPOBJDIR)/%: FORCE
$(MAKE) -C $(dir $@) $(notdir $@)
# Files under the faster/ sub-directory, however, are not meant to use the
# fallback
$(TOPOBJDIR)/faster/%: ;
# And files under dist/ are meant to be copied from their first dependency
# if there is no other rule.
$(TOPOBJDIR)/dist/%:
rm -f $@
cp $< $@
# Install files using install manifests
#
# The list of base directories is given in INSTALL_MANIFESTS. The
# corresponding install manifests are named correspondingly, with forward
# slashes replaced with underscores, and prefixed with `install_`. That is,
# the install manifest for `dist/bin` would be `install_dist_bin`.
$(addprefix install-,$(INSTALL_MANIFESTS)): install-%:
$(PYTHON) -m mozbuild.action.process_install_manifest \
--no-remove \
--no-remove-empty-directories \
$(TOPOBJDIR)/$* \
install_$(subst /,_,$*)
# Preprocessed files. Ideally they would be using install manifests but
# right now, it's not possible because of things like APP_BUILDID or
# nsURLFormatter.js.
# Things missing:
# - XULPPFLAGS
#
# The list of preprocessed files is defined in PP_TARGETS. The list is
# relative to TOPOBJDIR.
# The source file for each of those preprocessed files is defined as a Make
# dependency for the $(TOPOBJDIR)/path target. For example:
# PP_TARGETS = foo/bar
# $(TOPOBJDIR)/foo/bar: /path/to/source/for/foo/bar.in
# The file name for the source doesn't need to be different.
# Additionally, extra defines can be specified for a given preprocessing
# by setting the `defines` variable specifically for the given target.
# For example:
# $(TOPOBJDIR)/foo/bar: defines = -Dqux=foobar
$(addprefix $(TOPOBJDIR)/,$(PP_TARGETS)): Makefile
$(addprefix $(TOPOBJDIR)/,$(PP_TARGETS)): $(TOPOBJDIR)/%:
$(PYTHON) -m mozbuild.action.preprocessor \
--depend $(TOPOBJDIR)/faster/.deps/$(subst /,_,$*) \
-DAB_CD=en-US \
$(defines) \
$(ACDEFINES) \
$< \
-o $@
# Include the dependency files from the above preprocessed files rule.
$(foreach pp_target,$(PP_TARGETS), \
$(eval -include $(TOPOBJDIR)/faster/.deps/$(subst /,_,$(pp_target))))
# Install files from jar manifests. Ideally, they would be using install
# manifests, but the code to read jar manifests and emit appropriate
# install manifests is not there yet.
# Things missing:
# - XULPPFLAGS
# - DEFINES from config/config.mk
# - L10N
# - -e when USE_EXTENSION_MANIFEST is set in moz.build
#
# The list given in JAR_MN_TARGETS corresponds to the list of `jar-%` targets
# to be processed, with the `jar-` prefix stripped.
# The Makefile is expected to specify the source jar manifest as a dependency
# to each target. There is no expectation that the `jar-%` target name matches
# the source file name in any way. For example:
# JAR_MN_TARGETS = foo
# jar-foo: /path/to/some/jar.mn
# Additionally, extra defines can be specified for the processing of the jar
# manifest by settig the `defines` variable specifically for the given target.
# For example:
# jar-foo: defines = -Dqux=foo
# The default base path where files are going to be installed is `dist/bin`.
# It is possible to use a different path by setting the `install_target`
# variable. For example:
# jar-foo: install_target = dist/bin/foo
# When processing jar manifests, relative paths given inside a jar manifest
# can be resolved from an object directory. The default path for that object
# directory is the translation of the jar manifest directory path from the
# source directory to the object directory. That is, for
# $(TOPSRCDIR)/path/to/jar.mn, the default would be $(TOPOBJDIR)/path/to.
# In case a different path must be used for the object directory, the `objdir`
# variable can be set. For example:
# jar-foo: objdir=/some/other/path
jar-%: objdir ?= $(dir $(patsubst $(TOPSRCDIR)%,$(TOPOBJDIR)%,$<))
jar-%: install_target ?= dist/bin
jar-%:
cd $(objdir) && \
$(PYTHON) -m mozbuild.action.jar_maker \
-j $(TOPOBJDIR)/$(install_target)/chrome \
-t $(TOPSRCDIR) \
-f $(MOZ_CHROME_FILE_FORMAT) \
-c $(dir $<)/en-US \
-DAB_CD=en-US \
$(defines) \
$(ACDEFINES) \
$<
# Create some chrome manifests
# This rule is forced to run every time because it may be updating files that
# already exit.
#
# The list of chrome manifests is given in MANIFEST_TARGETS, relative to the
# top object directory. The content for those manifests is given in the
# `content` variable associated with the target. For example:
# MANIFEST_TARGETS = foo
# $(TOPOBJDIR)/foo: content = "manifest foo.manifest" "manifest bar.manifest"
$(addprefix $(TOPOBJDIR)/,$(MANIFEST_TARGETS)): FORCE
$(PYTHON) -m mozbuild.action.buildlist \
$@ \
$(content)
# ============================================================================
# Below is a set of additional dependencies and variables used to build things
# that are not supported by data in moz.build.
# GENERATED_FILES are not supported yet, and even if they were, the
# dependencies are missing information.
$(foreach p,linux osx windows,jar-browser-themes-$(p)-jar.mn): \
jar-browser-themes-%-jar.mn: \
$(TOPOBJDIR)/browser/themes/%/tab-selected-end.svg \
$(TOPOBJDIR)/browser/themes/%/tab-selected-start.svg
# These files are manually generated from
# toolkit/components/urlformatter/Makefile.in and are force-included so that
# the corresponding defines don't end up in the command lines.
KEYS = mozilla_api_key google_api_key google_oauth_api_key bing_api_key
$(TOPOBJDIR)/dist/bin/components/nsURLFormatter.js: \
$(addprefix $(TOPOBJDIR)/toolkit/components/urlformatter/, $(KEYS))
$(TOPOBJDIR)/dist/bin/components/nsURLFormatter.js: defines += \
$(addprefix -I $(TOPOBJDIR)/toolkit/components/urlformatter/,$(KEYS))
# Extra dependencies and/or definitions for preprocessed files.
$(TOPOBJDIR)/dist/bin/application.ini: $(TOPOBJDIR)/config/buildid
$(TOPOBJDIR)/dist/bin/application.ini: defines += \
-DAPP_BUILDID=$(shell cat $(TOPOBJDIR)/config/buildid)
# Files to build with the recursive backend and simply copy
$(TOPOBJDIR)/dist/bin/greprefs.js: $(TOPOBJDIR)/modules/libpref/greprefs.js
$(TOPOBJDIR)/dist/bin/platform.ini: $(TOPOBJDIR)/toolkit/xre/platform.ini
$(TOPOBJDIR)/dist/bin/webapprt/webapprt.ini: $(TOPOBJDIR)/webapprt/webapprt.ini

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

@ -1,202 +0,0 @@
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
##############################################################################
##
## Name: glibcversion.sh - Print __GLIBC__ version if gnu libc 2 is
## found.
##
## Description: This script is needed by the mozilla build system. It needs
## to determine whether the current platform (mostly the
## various linux "platforms") are based on the gnu libc2. This
## information is later used in mozilla to determine whether
## gnu libc 2 specific "features" need to be handled, such
## as broken locales.
##
## Author: Ramiro Estrugo <ramiro@netscape.com>
##
##############################################################################
##
## Command Line Flags Supported:
##
## -g | --is-glibc2: Print True/False if detected __GLIBC__.
##
## -v | --print-version: Print value of __GLIBC__ if found, or none.
##
## -o | --set-object-name: Set object name for current system.
## -cc | --set-compiler: Set compiler for building test program.
##
##
## Constants
##
GLIBC_PROG_PREFIX=./get_glibc_info
##
## Defaults
##
GLIBC_PRINT_IS_GLIBC2=False
GLIBC_PRINT_VERSION=False
GLIBC_OBJECT_NAME=`uname`-`uname -r`
GLIBC_CC=cc
function glibc_usage()
{
echo
echo "Usage: `basename $0` [options]"
echo
echo " -g, --is-glibc2: Print True/False if detected __GLIBC__."
echo
echo " -v, --print-version: Print value of __GLIBC__ if found, or none."
echo
echo " -o, --set-object-name: Set object name for current system."
echo " -cc, --set-compiler: Set compiler for building test program."
echo
echo " -h, --help: Print this blurb."
echo
echo "The default is '-v' if no options are given."
echo
}
##
## Parse the command line
##
while [ "$*" ]; do
case $1 in
-h | --help)
shift
glibc_usage
exit 0
;;
-g | --is-glibc2)
shift
GLIBC_PRINT_IS_GLIBC2=True
;;
-v | --print-version)
shift
GLIBC_PRINT_VERSION=True
;;
-o | --set-object-name)
shift
GLIBC_OBJECT_NAME="$1"
shift
;;
-cc | --set-compiler)
shift
GLIBC_CC="$1"
shift
;;
-*)
echo "`basename $0`: invalid option '$1'"
shift
glibc_usage
exit 0
;;
esac
done
##
## Motif info program name
##
GLIBC_PROG="$GLIBC_PROG_PREFIX"_"$GLIBC_OBJECT_NAME"
GLIBC_SRC="$GLIBC_PROG_PREFIX"_"$GLIBC_OBJECT_NAME.c"
##
## Cleanup the dummy test source/program
##
function glibc_cleanup()
{
true
# rm -f $GLIBC_PROG
# rm -f $GLIBC_SRC
}
glibc_cleanup
if [ ! -f $GLIBC_SRC ]
then
cat << EOF > $GLIBC_SRC
#include <stdio.h>
int main(int argc,char ** argv)
{
#ifdef __GLIBC__
fprintf(stdout,"%d\n",__GLIBC__);
#else
fprintf(stdout,"none\n");
#endif
return 0;
}
EOF
fi
if [ ! -f $GLIBC_SRC ]
then
echo
echo "Could not create test program source $GLIBC_SRC."
echo
glibc_cleanup
exit
fi
##
## Compile the dummy test program if needed
##
if [ ! -x $GLIBC_PROG ]
then
$GLIBC_CC -o $GLIBC_PROG $GLIBC_SRC
fi
if [ ! -x $GLIBC_PROG ]
then
echo
echo "Could not create test program $GLIBC_PROG."
echo
glibc_cleanup
exit
fi
##
## Execute the dummy test program
##
GLIBC_PROG_OUTPUT=`$GLIBC_PROG`
##
## -g | --is-glibc2
##
if [ "$GLIBC_PRINT_IS_GLIBC2" = "True" ]
then
if [ "$GLIBC_PROG_OUTPUT" = "2" ]
then
echo True
else
echo False
fi
glibc_cleanup
exit 0
fi
echo $GLIBC_PROG_OUTPUT
glibc_cleanup

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

@ -137,6 +137,8 @@ MOZ_BUILD_ROOT=`pwd -W 2>/dev/null || pwd`
MOZ_PYTHON
MOZ_BUILD_BACKEND
MOZ_DEFAULT_COMPILER
COMPILE_ENVIRONMENT=1

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

@ -56,6 +56,10 @@ function test() {
]);
checkState({ frame: 0, source: 0, line: 5 });
// Need to refocus the stack frame due to a focus bug in e10s
// (See Bug 1205482)
focusCurrentStackFrame();
yield promise.all([
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
waitForSourceAndCaret(gPanel, "-02.js", 6),
@ -64,13 +68,16 @@ function test() {
]);
checkState({ frame: 1, source: 1, line: 6 });
// Need to refocus the stack frame due to a focus bug in e10s
// (See Bug 1205482)
focusCurrentStackFrame();
yield promise.all([
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
waitForSourceAndCaret(gPanel, "-01.js", 5),
waitForEditorLocationSet(gPanel),
EventUtils.sendKey("HOME", gDebugger)
]);
checkState({ frame: 0, source: 0, line: 5 });
});
}

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

@ -1732,7 +1732,7 @@ var Scratchpad = {
this._onPaste = WebConsoleUtils.pasteHandlerGen(this.editor.container.contentDocument.body,
document.querySelector('#scratchpad-notificationbox'),
msg, okstring);
editorElement.addEventListener("paste", this._onPaste);
editorElement.addEventListener("paste", this._onPaste, true);
editorElement.addEventListener("drop", this._onPaste);
this.editor.on("saveRequested", () => this.saveFile());
this.editor.focus();
@ -1808,7 +1808,7 @@ var Scratchpad = {
CloseObserver.uninit();
if (this._onPaste) {
let editorElement = document.querySelector("#scratchpad-editor");
editorElement.removeEventListener("paste", this._onPaste);
editorElement.removeEventListener("paste", this._onPaste, true);
editorElement.removeEventListener("drop", this._onPaste);
this._onPaste = null;
}

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

@ -1,4 +1,4 @@
Copyright (C) 2013 by Marijn Haverbeke <marijnh@gmail.com>
Copyright (C) 2015 by Marijn Haverbeke <marijnh@gmail.com> and others
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

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

@ -5,7 +5,7 @@ code, and optionally help with indentation.
# Upgrade
Currently used version is 4.2.0. To upgrade, download a new version of
Currently used version is 5.7.0. To upgrade, download a new version of
CodeMirror from the project's page [1] and replace all JavaScript and
CSS files inside the codemirror directory [2].
@ -41,73 +41,40 @@ below.
# License
The following files in this directory are licensed according to the contents
in the LICENSE file:
* codemirror.css
* codemirror.js
* comment/comment.js
* comment/continue-comment.js
* activeline.js
* dialog/dialog.css
* dialog/dialog.js
* edit/closebrackets.js
* edit/closetag.js
* edit/continuelist.js
* edit/matchbrackets.js
* edit/matchtags.js
* edit/trailingspace.js
* fold/foldcode.js
* fold/brace-fold.js
* fold/comment-fold.js
* fold/xml-fold.js
* fold/foldgutter.js
* hint/show-hint.js
* keymap/emacs.js
* keymap/sublime.js
* keymap/vim.js
* mode/xml.js
* mode/css.js
* mode/javascript.js
* mode/clike.js
* mode/htmlmixed.js
* search/match-highlighter.js
* search/search.js
* search/searchcursor.js
* tern/tern.js
* tern/tern.css
* test/codemirror.html
* test/cm_comment_test.js
* test/cm_doc_test.js
* test/cm_driver.js
* test/cm_mode_javascript_test.js
* test/cm_mode_test.css
* test/cm_mode_test.js
* test/cm_multi_test.js
* test/cm_search_test.js
* test/cm_test.js
* test/cm_sublime_test.js
* test/cm_vim_test.js
* test/cm_emacs_test.js
The following files in this directory and devtools/client/sourceeditor/test/codemirror/
are licensed according to the contents in the LICENSE file.
# Localization patches
diff --git a/devtools/client/sourceeditor/codemirror/search/search.js b/devtools/client/sourceeditor/codemirror/search/search.js
--- a/devtools/client/sourceeditor/codemirror/search/search.js
+++ b/devtools/client/sourceeditor/codemirror/search/search.js
@@ -62,19 +62,31 @@
if (isRE) {
query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i");
if (query.test("")) query = /x^/;
} else if (query == "") {
query = /x^/;
diff --git a/devtools/client/sourceeditor/codemirror/addon/search/search.js b/devtools/client/sourceeditor/codemirror/addon/search/search.js
--- a/devtools/client/sourceeditor/codemirror/addon/search/search.js
+++ b/devtools/client/sourceeditor/codemirror/addon/search/search.js
@@ -92,32 +92,47 @@
} else {
query = parseString(query)
}
if (typeof query == "string" ? query == "" : query.test(""))
query = /x^/;
return query;
}
- var queryDialog =
- 'Search: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
- 'Search: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
+ var queryDialog;
function doSearch(cm, rev) {
function startSearch(cm, state, query) {
state.queryText = query;
state.query = parseQuery(query);
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
cm.addOverlay(state.overlay);
if (cm.showMatchesOnScrollbar) {
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
}
}
function doSearch(cm, rev, persistent) {
+ if (!queryDialog) {
+ let doc = cm.getWrapperElement().ownerDocument;
+ let inp = doc.createElement("input");
@ -123,14 +90,15 @@ diff --git a/devtools/client/sourceeditor/codemirror/search/search.js b/devtools
+ queryDialog.appendChild(inp);
+ queryDialog.style.display = "flex";
+ }
+
var state = getSearchState(cm);
if (state.query) return findNext(cm, rev);
dialog(cm, queryDialog, "Search for:", cm.getSelection(), function(query) {
cm.operation(function() {
if (!query || state.query) return;
state.query = parseQuery(query);
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
var q = cm.getSelection() || state.lastQuery;
if (persistent && cm.openDialog) {
var hiding = null
persistentDialog(cm, queryDialog, q, function(query, event) {
CodeMirror.e_stop(event);
if (!query) return;
# Footnotes

13
devtools/client/sourceeditor/codemirror/addon/comment/comment.js поставляемый Normal file → Executable file
Просмотреть файл

@ -109,7 +109,7 @@
CodeMirror.defineExtension("uncomment", function(from, to, options) {
if (!options) options = noOptions;
var self = this, mode = self.getModeAt(from);
var end = Math.min(to.line, self.lastLine()), start = Math.min(from.line, end);
var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end);
// Try finding line comments
var lineString = options.lineComment || mode.lineComment, lines = [];
@ -153,6 +153,17 @@
!/comment/.test(self.getTokenTypeAt(Pos(end, close + 1))))
return false;
// Avoid killing block comments completely outside the selection.
// Positions of the last startString before the start of the selection, and the first endString after it.
var lastStart = startLine.lastIndexOf(startString, from.ch);
var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length);
if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false;
// Positions of the first endString after the end of the selection, and the last startString before it.
firstEnd = endLine.indexOf(endString, to.ch);
var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch);
lastStart = (firstEnd == -1 || almostLastStart == -1) ? -1 : to.ch + almostLastStart;
if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false;
self.operation(function() {
self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)),
Pos(end, close + endString.length));

4
devtools/client/sourceeditor/codemirror/addon/dialog/dialog.css поставляемый Normal file → Executable file
Просмотреть файл

@ -1,11 +1,11 @@
.CodeMirror-dialog {
position: absolute;
left: 0; right: 0;
background: white;
background: inherit;
z-index: 15;
padding: .1em .8em;
overflow: hidden;
color: #333;
color: inherit;
}
.CodeMirror-dialog-top {

64
devtools/client/sourceeditor/codemirror/addon/dialog/dialog.js поставляемый Normal file → Executable file
Просмотреть файл

@ -15,11 +15,11 @@
var wrap = cm.getWrapperElement();
var dialog;
dialog = wrap.appendChild(document.createElement("div"));
if (bottom) {
if (bottom)
dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
} else {
else
dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
}
if (typeof template == "string") {
dialog.innerHTML = template;
} else { // Assuming it's a detached DOM element.
@ -35,40 +35,61 @@
}
CodeMirror.defineExtension("openDialog", function(template, callback, options) {
if (!options) options = {};
closeNotification(this, null);
var dialog = dialogDiv(this, template, options && options.bottom);
var dialog = dialogDiv(this, template, options.bottom);
var closed = false, me = this;
function close() {
if (closed) return;
closed = true;
dialog.parentNode.removeChild(dialog);
function close(newVal) {
if (typeof newVal == 'string') {
inp.value = newVal;
} else {
if (closed) return;
closed = true;
dialog.parentNode.removeChild(dialog);
me.focus();
if (options.onClose) options.onClose(dialog);
}
}
var inp = dialog.getElementsByTagName("input")[0], button;
if (inp) {
if (options && options.value) inp.value = options.value;
if (options.value) {
inp.value = options.value;
if (options.selectValueOnOpen !== false) {
inp.select();
}
}
if (options.onInput)
CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);});
if (options.onKeyUp)
CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
CodeMirror.on(inp, "keydown", function(e) {
if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
if (e.keyCode == 13 || e.keyCode == 27) {
if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {
inp.blur();
CodeMirror.e_stop(e);
close();
me.focus();
if (e.keyCode == 13) callback(inp.value);
}
if (e.keyCode == 13) callback(inp.value, e);
});
if (options && options.onKeyUp) {
CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
}
if (options && options.value) inp.value = options.value;
if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
inp.focus();
CodeMirror.on(inp, "blur", close);
} else if (button = dialog.getElementsByTagName("button")[0]) {
CodeMirror.on(button, "click", function() {
close();
me.focus();
});
if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close);
button.focus();
CodeMirror.on(button, "blur", close);
}
return close;
});
@ -113,8 +134,8 @@
CodeMirror.defineExtension("openNotification", function(template, options) {
closeNotification(this, close);
var dialog = dialogDiv(this, template, options && options.bottom);
var duration = options && (options.duration === undefined ? 5000 : options.duration);
var closed = false, doneTimer;
var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000;
function close() {
if (closed) return;
@ -127,7 +148,10 @@
CodeMirror.e_preventDefault(e);
close();
});
if (duration)
doneTimer = setTimeout(close, options.duration);
doneTimer = setTimeout(close, duration);
return close;
});
});

286
devtools/client/sourceeditor/codemirror/addon/edit/closebrackets.js поставляемый Normal file → Executable file
Просмотреть файл

@ -9,135 +9,187 @@
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
var DEFAULT_BRACKETS = "()[]{}''\"\"";
var DEFAULT_EXPLODE_ON_ENTER = "[]{}";
var SPACE_CHAR_REGEX = /\s/;
var defaults = {
pairs: "()[]{}''\"\"",
triples: "",
explode: "[]{}"
};
var Pos = CodeMirror.Pos;
CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
if (old != CodeMirror.Init && old)
cm.removeKeyMap("autoCloseBrackets");
if (!val) return;
var pairs = DEFAULT_BRACKETS, explode = DEFAULT_EXPLODE_ON_ENTER;
if (typeof val == "string") pairs = val;
else if (typeof val == "object") {
if (val.pairs != null) pairs = val.pairs;
if (val.explode != null) explode = val.explode;
if (old && old != CodeMirror.Init) {
cm.removeKeyMap(keyMap);
cm.state.closeBrackets = null;
}
if (val) {
cm.state.closeBrackets = val;
cm.addKeyMap(keyMap);
}
var map = buildKeymap(pairs);
if (explode) map.Enter = buildExplodeHandler(explode);
cm.addKeyMap(map);
});
function getOption(conf, name) {
if (name == "pairs" && typeof conf == "string") return conf;
if (typeof conf == "object" && conf[name] != null) return conf[name];
return defaults[name];
}
var bind = defaults.pairs + "`";
var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
for (var i = 0; i < bind.length; i++)
keyMap["'" + bind.charAt(i) + "'"] = handler(bind.charAt(i));
function handler(ch) {
return function(cm) { return handleChar(cm, ch); };
}
function getConfig(cm) {
var deflt = cm.state.closeBrackets;
if (!deflt) return null;
var mode = cm.getModeAt(cm.getCursor());
return mode.closeBrackets || deflt;
}
function handleBackspace(cm) {
var conf = getConfig(cm);
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
var pairs = getOption(conf, "pairs");
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
for (var i = ranges.length - 1; i >= 0; i--) {
var cur = ranges[i].head;
cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
}
}
function handleEnter(cm) {
var conf = getConfig(cm);
var explode = conf && getOption(conf, "explode");
if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
cm.operation(function() {
cm.replaceSelection("\n\n", null);
cm.execCommand("goCharLeft");
ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var line = ranges[i].head.line;
cm.indentLine(line, null, true);
cm.indentLine(line + 1, null, true);
}
});
}
function contractSelection(sel) {
var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0;
return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)),
head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))};
}
function handleChar(cm, ch) {
var conf = getConfig(cm);
if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
var pairs = getOption(conf, "pairs");
var pos = pairs.indexOf(ch);
if (pos == -1) return CodeMirror.Pass;
var triples = getOption(conf, "triples");
var identical = pairs.charAt(pos + 1) == ch;
var ranges = cm.listSelections();
var opening = pos % 2 == 0;
var type, next;
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], cur = range.head, curType;
var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
if (opening && !range.empty()) {
curType = "surround";
} else if ((identical || !opening) && next == ch) {
if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
curType = "skipThree";
else
curType = "skip";
} else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch &&
(cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) {
curType = "addFour";
} else if (identical) {
if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both";
else return CodeMirror.Pass;
} else if (opening && (cm.getLine(cur.line).length == cur.ch ||
isClosingBracket(next, pairs) ||
/\s/.test(next))) {
curType = "both";
} else {
return CodeMirror.Pass;
}
if (!type) type = curType;
else if (type != curType) return CodeMirror.Pass;
}
var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
var right = pos % 2 ? ch : pairs.charAt(pos + 1);
cm.operation(function() {
if (type == "skip") {
cm.execCommand("goCharRight");
} else if (type == "skipThree") {
for (var i = 0; i < 3; i++)
cm.execCommand("goCharRight");
} else if (type == "surround") {
var sels = cm.getSelections();
for (var i = 0; i < sels.length; i++)
sels[i] = left + sels[i] + right;
cm.replaceSelections(sels, "around");
sels = cm.listSelections().slice();
for (var i = 0; i < sels.length; i++)
sels[i] = contractSelection(sels[i]);
cm.setSelections(sels);
} else if (type == "both") {
cm.replaceSelection(left + right, null);
cm.triggerElectric(left + right);
cm.execCommand("goCharLeft");
} else if (type == "addFour") {
cm.replaceSelection(left + left + left + left, "before");
cm.execCommand("goCharRight");
}
});
}
function isClosingBracket(ch, pairs) {
var pos = pairs.lastIndexOf(ch);
return pos > -1 && pos % 2 == 1;
}
function charsAround(cm, pos) {
var str = cm.getRange(Pos(pos.line, pos.ch - 1),
Pos(pos.line, pos.ch + 1));
return str.length == 2 ? str : null;
}
function buildKeymap(pairs) {
var map = {
name : "autoCloseBrackets",
Backspace: function(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
for (var i = ranges.length - 1; i >= 0; i--) {
var cur = ranges[i].head;
cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
}
}
};
var closingBrackets = "";
for (var i = 0; i < pairs.length; i += 2) (function(left, right) {
if (left != right) closingBrackets += right;
map["'" + left + "'"] = function(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), type, next;
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], cur = range.head, curType;
if (left == "'" && cm.getTokenTypeAt(cur) == "comment")
return CodeMirror.Pass;
var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
if (!range.empty())
curType = "surround";
else if (left == right && next == right) {
if (cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == left + left + left)
curType = "skipThree";
else
curType = "skip";
} else if (left == right && cur.ch > 1 &&
cm.getRange(Pos(cur.line, cur.ch - 2), cur) == left + left &&
(cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != left))
curType = "addFour";
else if (left == right && CodeMirror.isWordChar(next))
return CodeMirror.Pass;
else if (cm.getLine(cur.line).length == cur.ch || closingBrackets.indexOf(next) >= 0 || SPACE_CHAR_REGEX.test(next))
curType = "both";
else
return CodeMirror.Pass;
if (!type) type = curType;
else if (type != curType) return CodeMirror.Pass;
}
cm.operation(function() {
if (type == "skip") {
cm.execCommand("goCharRight");
} else if (type == "skipThree") {
for (var i = 0; i < 3; i++)
cm.execCommand("goCharRight");
} else if (type == "surround") {
var sels = cm.getSelections();
for (var i = 0; i < sels.length; i++)
sels[i] = left + sels[i] + right;
cm.replaceSelections(sels, "around");
} else if (type == "both") {
cm.replaceSelection(left + right, null);
cm.execCommand("goCharLeft");
} else if (type == "addFour") {
cm.replaceSelection(left + left + left + left, "before");
cm.execCommand("goCharRight");
}
});
};
if (left != right) map["'" + right + "'"] = function(cm) {
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i];
if (!range.empty() ||
cm.getRange(range.head, Pos(range.head.line, range.head.ch + 1)) != right)
return CodeMirror.Pass;
}
cm.execCommand("goCharRight");
};
})(pairs.charAt(i), pairs.charAt(i + 1));
return map;
}
function buildExplodeHandler(pairs) {
return function(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var around = charsAround(cm, ranges[i].head);
if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
cm.operation(function() {
cm.replaceSelection("\n\n", null);
cm.execCommand("goCharLeft");
ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
var line = ranges[i].head.line;
cm.indentLine(line, null, true);
cm.indentLine(line + 1, null, true);
}
});
};
// Project the token type that will exists after the given char is
// typed, and use it to determine whether it would cause the start
// of a string token.
function enteringString(cm, pos, ch) {
var line = cm.getLine(pos.line);
var token = cm.getTokenAt(pos);
if (/\bstring2?\b/.test(token.type)) return false;
var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4);
stream.pos = stream.start = token.start;
for (;;) {
var type1 = cm.getMode().token(stream, token.state);
if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1);
stream.start = stream.pos;
}
}
});

42
devtools/client/sourceeditor/codemirror/addon/edit/closetag.js поставляемый Normal file → Executable file
Просмотреть файл

@ -94,23 +94,51 @@
}
}
function autoCloseSlash(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
function autoCloseCurrent(cm, typingSlash) {
var ranges = cm.listSelections(), replacements = [];
var head = typingSlash ? "/" : "</";
for (var i = 0; i < ranges.length; i++) {
if (!ranges[i].empty()) return CodeMirror.Pass;
var pos = ranges[i].head, tok = cm.getTokenAt(pos);
var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
if (tok.type == "string" || tok.string.charAt(0) != "<" ||
tok.start != pos.ch - 1 || inner.mode.name != "xml" ||
!state.context || !state.context.tagName ||
closingTagExists(cm, state.context.tagName, pos, state))
if (typingSlash && (tok.type == "string" || tok.string.charAt(0) != "<" ||
tok.start != pos.ch - 1))
return CodeMirror.Pass;
replacements[i] = "/" + state.context.tagName + ">";
// Kludge to get around the fact that we are not in XML mode
// when completing in JS/CSS snippet in htmlmixed mode. Does not
// work for other XML embedded languages (there is no general
// way to go from a mixed mode to its current XML state).
var replacement;
if (inner.mode.name != "xml") {
if (cm.getMode().name == "htmlmixed" && inner.mode.name == "javascript")
replacement = head + "script";
else if (cm.getMode().name == "htmlmixed" && inner.mode.name == "css")
replacement = head + "style";
else
return CodeMirror.Pass;
} else {
if (!state.context || !state.context.tagName ||
closingTagExists(cm, state.context.tagName, pos, state))
return CodeMirror.Pass;
replacement = head + state.context.tagName;
}
if (cm.getLine(pos.line).charAt(tok.end) != ">") replacement += ">";
replacements[i] = replacement;
}
cm.replaceSelections(replacements);
ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++)
if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line)
cm.indentLine(ranges[i].head.line);
}
function autoCloseSlash(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
return autoCloseCurrent(cm, true);
}
CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); };
function indexOf(collection, elt) {
if (collection.indexOf) return collection.indexOf(elt);
for (var i = 0, e = collection.length; i < e; ++i)

33
devtools/client/sourceeditor/codemirror/addon/edit/continuelist.js поставляемый Normal file → Executable file
Просмотреть файл

@ -11,26 +11,39 @@
})(function(CodeMirror) {
"use strict";
var listRE = /^(\s*)([*+-]|(\d+)\.)(\s*)/,
unorderedBullets = "*+-";
var listRE = /^(\s*)(>[> ]*|[*+-]\s|(\d+)([.)]))(\s*)/,
emptyListRE = /^(\s*)(>[> ]*|[*+-]|(\d+)[.)])(\s*)$/,
unorderedListRE = /[*+-]\s/;
CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) {
if (cm.getOption("disableInput")) return CodeMirror.Pass;
var ranges = cm.listSelections(), replacements = [];
for (var i = 0; i < ranges.length; i++) {
var pos = ranges[i].head, match;
var inList = cm.getStateAfter(pos.line).list !== false;
var pos = ranges[i].head;
var eolState = cm.getStateAfter(pos.line);
var inList = eolState.list !== false;
var inQuote = eolState.quote !== 0;
if (!ranges[i].empty() || !inList || !(match = cm.getLine(pos.line).match(listRE))) {
var line = cm.getLine(pos.line), match = listRE.exec(line);
if (!ranges[i].empty() || (!inList && !inQuote) || !match) {
cm.execCommand("newlineAndIndent");
return;
}
var indent = match[1], after = match[4];
var bullet = unorderedBullets.indexOf(match[2]) >= 0
? match[2]
: (parseInt(match[3], 10) + 1) + ".";
if (emptyListRE.test(line)) {
cm.replaceRange("", {
line: pos.line, ch: 0
}, {
line: pos.line, ch: pos.ch + 1
});
replacements[i] = "\n";
} else {
var indent = match[1], after = match[5];
var bullet = unorderedListRE.test(match[2]) || match[2].indexOf(">") >= 0
? match[2]
: (parseInt(match[3], 10) + 1) + match[4];
replacements[i] = "\n" + indent + bullet + after;
replacements[i] = "\n" + indent + bullet + after;
}
}
cm.replaceSelections(replacements);

2
devtools/client/sourceeditor/codemirror/addon/edit/matchbrackets.js поставляемый Normal file → Executable file
Просмотреть файл

@ -81,7 +81,7 @@
if (marks.length) {
// Kludge to work around the IE bug from issue #1193, where text
// input stops going to the textare whever this fires.
if (ie_lt8 && cm.state.focused) cm.display.input.focus();
if (ie_lt8 && cm.state.focused) cm.focus();
var clear = function() {
cm.operation(function() {

4
devtools/client/sourceeditor/codemirror/addon/fold/foldcode.js поставляемый Normal file → Executable file
Просмотреть файл

@ -142,4 +142,8 @@
return editorOptions[name];
return defaultOptions[name];
}
CodeMirror.defineExtension("foldOption", function(options, name) {
return getOption(this, options, name);
});
});

1
devtools/client/sourceeditor/codemirror/addon/fold/foldgutter.css поставляемый Normal file → Executable file
Просмотреть файл

@ -10,7 +10,6 @@
}
.CodeMirror-foldgutter-open,
.CodeMirror-foldgutter-folded {
color: #555;
cursor: pointer;
}
.CodeMirror-foldgutter-open:after {

30
devtools/client/sourceeditor/codemirror/addon/fold/foldgutter.js поставляемый Normal file → Executable file
Просмотреть файл

@ -52,13 +52,13 @@
function isFolded(cm, line) {
var marks = cm.findMarksAt(Pos(line));
for (var i = 0; i < marks.length; ++i)
if (marks[i].__isFold && marks[i].find().from.line == line) return true;
if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i];
}
function marker(spec) {
if (typeof spec == "string") {
var elt = document.createElement("div");
elt.className = spec;
elt.className = spec + " CodeMirror-guttermarker-subtle";
return elt;
} else {
return spec.cloneNode(true);
@ -67,14 +67,16 @@
function updateFoldInfo(cm, from, to) {
var opts = cm.state.foldGutter.options, cur = from;
var minSize = cm.foldOption(opts, "minFoldSize");
var func = cm.foldOption(opts, "rangeFinder");
cm.eachLine(from, to, function(line) {
var mark = null;
if (isFolded(cm, cur)) {
mark = marker(opts.indicatorFolded);
} else {
var pos = Pos(cur, 0), func = opts.rangeFinder || CodeMirror.fold.auto;
var pos = Pos(cur, 0);
var range = func && func(cm, pos);
if (range && range.from.line + 1 < range.to.line)
if (range && range.to.line - range.from.line >= minSize)
mark = marker(opts.indicatorOpen);
}
cm.setGutterMarker(line, opts.gutter, mark);
@ -92,20 +94,28 @@
}
function onGutterClick(cm, line, gutter) {
var opts = cm.state.foldGutter.options;
var state = cm.state.foldGutter;
if (!state) return;
var opts = state.options;
if (gutter != opts.gutter) return;
cm.foldCode(Pos(line, 0), opts.rangeFinder);
var folded = isFolded(cm, line);
if (folded) folded.clear();
else cm.foldCode(Pos(line, 0), opts.rangeFinder);
}
function onChange(cm) {
var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
var state = cm.state.foldGutter;
if (!state) return;
var opts = state.options;
state.from = state.to = 0;
clearTimeout(state.changeUpdate);
state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
}
function onViewportChange(cm) {
var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;
var state = cm.state.foldGutter;
if (!state) return;
var opts = state.options;
clearTimeout(state.changeUpdate);
state.changeUpdate = setTimeout(function() {
var vp = cm.getViewport();
@ -127,7 +137,9 @@
}
function onFold(cm, from) {
var state = cm.state.foldGutter, line = from.line;
var state = cm.state.foldGutter;
if (!state) return;
var line = from.line;
if (line >= state.from && line < state.to)
updateFoldInfo(cm, line, line + 1);
}

3
devtools/client/sourceeditor/codemirror/addon/fold/xml-fold.js поставляемый Normal file → Executable file
Просмотреть файл

@ -151,8 +151,9 @@
if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return;
var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch);
var start = end && toTagStart(iter);
if (!end || end == "selfClose" || !start || cmp(iter, pos) > 0) return;
if (!end || !start || cmp(iter, pos) > 0) return;
var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]};
if (end == "selfClose") return {open: here, close: null, at: "open"};
if (start[1]) { // closing tag
return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"};

149
devtools/client/sourceeditor/codemirror/addon/hint/show-hint.js поставляемый Normal file → Executable file
Просмотреть файл

@ -30,29 +30,39 @@
if (this.state.completionActive) this.state.completionActive.close();
var completion = this.state.completionActive = new Completion(this, options);
var getHints = completion.options.hint;
if (!getHints) return;
if (!completion.options.hint) return;
CodeMirror.signal(this, "startCompletion", this);
if (getHints.async)
getHints(this, function(hints) { completion.showHints(hints); }, completion.options);
else
return completion.showHints(getHints(this, completion.options));
completion.update(true);
});
function Completion(cm, options) {
this.cm = cm;
this.options = this.buildOptions(options);
this.widget = this.onClose = null;
this.widget = null;
this.debounce = 0;
this.tick = 0;
this.startPos = this.cm.getCursor();
this.startLen = this.cm.getLine(this.startPos.line).length;
var self = this;
cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
}
var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
return setTimeout(fn, 1000/60);
};
var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
Completion.prototype = {
close: function() {
if (!this.active()) return;
this.cm.state.completionActive = null;
this.tick = null;
this.cm.off("cursorActivity", this.activityFunc);
if (this.widget && this.data) CodeMirror.signal(this.data, "close");
if (this.widget) this.widget.close();
if (this.onClose) this.onClose();
CodeMirror.signal(this.cm, "endCompletion", this.cm);
},
@ -69,74 +79,51 @@
this.close();
},
showHints: function(data) {
if (!data || !data.list.length || !this.active()) return this.close();
cursorActivity: function() {
if (this.debounce) {
cancelAnimationFrame(this.debounce);
this.debounce = 0;
}
if (this.options.completeSingle && data.list.length == 1)
this.pick(data, 0);
else
this.showWidget(data);
var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
(pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
this.close();
} else {
var self = this;
this.debounce = requestAnimationFrame(function() {self.update();});
if (this.widget) this.widget.disable();
}
},
showWidget: function(data) {
this.widget = new Widget(this, data);
CodeMirror.signal(data, "shown");
var debounce = 0, completion = this, finished;
var closeOn = this.options.closeCharacters;
var startPos = this.cm.getCursor(), startLen = this.cm.getLine(startPos.line).length;
var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
return setTimeout(fn, 1000/60);
};
var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
function done() {
if (finished) return;
finished = true;
completion.close();
completion.cm.off("cursorActivity", activity);
if (data) CodeMirror.signal(data, "close");
update: function(first) {
if (this.tick == null) return;
if (!this.options.hint.async) {
this.finishUpdate(this.options.hint(this.cm, this.options), first);
} else {
var myTick = ++this.tick, self = this;
this.options.hint(this.cm, function(data) {
if (self.tick == myTick) self.finishUpdate(data, first);
}, this.options);
}
},
function update() {
if (finished) return;
CodeMirror.signal(data, "update");
var getHints = completion.options.hint;
if (getHints.async)
getHints(completion.cm, finishUpdate, completion.options);
else
finishUpdate(getHints(completion.cm, completion.options));
}
function finishUpdate(data_) {
data = data_;
if (finished) return;
if (!data || !data.list.length) return done();
if (completion.widget) completion.widget.close();
completion.widget = new Widget(completion, data);
}
finishUpdate: function(data, first) {
if (this.data) CodeMirror.signal(this.data, "update");
if (data && this.data && CodeMirror.cmpPos(data.from, this.data.from)) data = null;
this.data = data;
function clearDebounce() {
if (debounce) {
cancelAnimationFrame(debounce);
debounce = 0;
}
}
function activity() {
clearDebounce();
var pos = completion.cm.getCursor(), line = completion.cm.getLine(pos.line);
if (pos.line != startPos.line || line.length - pos.ch != startLen - startPos.ch ||
pos.ch < startPos.ch || completion.cm.somethingSelected() ||
(pos.ch && closeOn.test(line.charAt(pos.ch - 1)))) {
completion.close();
var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
if (this.widget) this.widget.close();
if (data && data.list.length) {
if (picked && data.list.length == 1) {
this.pick(data, 0);
} else {
debounce = requestAnimationFrame(update);
if (completion.widget) completion.widget.close();
this.widget = new Widget(this, data);
CodeMirror.signal(data, "shown");
}
}
this.cm.on("cursorActivity", activity);
this.onClose = done;
},
buildOptions: function(options) {
@ -201,6 +188,7 @@
function Widget(completion, data) {
this.completion = completion;
this.data = data;
this.picked = false;
var widget = this, cm = completion.cm;
var hints = this.hints = document.createElement("ul");
@ -228,9 +216,9 @@
(completion.options.container || document.body).appendChild(hints);
var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
if (overlapY > 0) {
var height = box.bottom - box.top, curTop = box.top - (pos.bottom - pos.top);
var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
if (curTop - height > 0) { // Fits above cursor
hints.style.top = (top = curTop - height) + "px";
hints.style.top = (top = pos.top - height) + "px";
below = false;
} else if (height > winH) {
hints.style.height = (winH - 5) + "px";
@ -243,7 +231,7 @@
}
}
}
var overlapX = box.left - winW;
var overlapX = box.right - winW;
if (overlapX > 0) {
if (box.right - box.left > winW) {
hints.style.width = (winW - 5) + "px";
@ -315,6 +303,13 @@
cm.off("scroll", this.onScroll);
},
disable: function() {
this.completion.cm.removeKeyMap(this.keyMap);
var widget = this;
this.keyMap = {Enter: function() { widget.picked = true; }};
this.completion.cm.addKeyMap(this.keyMap);
},
pick: function() {
this.completion.pick(this.data, this.selectedHint);
},
@ -357,18 +352,20 @@
CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
var cur = cm.getCursor(), token = cm.getTokenAt(cur);
var to = CodeMirror.Pos(cur.line, token.end);
if (token.string && /\w/.test(token.string[token.string.length - 1])) {
var term = token.string, from = CodeMirror.Pos(cur.line, token.start);
} else {
var term = "", from = to;
}
var found = [];
for (var i = 0; i < options.words.length; i++) {
var word = options.words[i];
if (word.slice(0, token.string.length) == token.string)
if (word.slice(0, term.length) == term)
found.push(word);
}
if (found.length) return {
list: found,
from: CodeMirror.Pos(cur.line, token.start),
to: CodeMirror.Pos(cur.line, token.end)
};
if (found.length) return {list: found, from: from, to: to};
});
CodeMirror.commands.autocomplete = CodeMirror.showHint;

32
devtools/client/sourceeditor/codemirror/addon/search/match-highlighter.js поставляемый Normal file → Executable file
Просмотреть файл

@ -8,12 +8,15 @@
// document.
//
// The option can be set to true to simply enable it, or to a
// {minChars, style, showToken} object to explicitly configure it.
// minChars is the minimum amount of characters that should be
// {minChars, style, wordsOnly, showToken, delay} object to explicitly
// configure it. minChars is the minimum amount of characters that should be
// selected for the behavior to occur, and style is the token style to
// apply to the matches. This will be prefixed by "cm-" to create an
// actual CSS class name. showToken, when enabled, will cause the
// current token to be highlighted when nothing is selected.
// actual CSS class name. If wordsOnly is enabled, the matches will be
// highlighted only if the selected text is a word. showToken, when enabled,
// will cause the current token to be highlighted when nothing is selected.
// delay is used to specify how much time to wait, in milliseconds, before
// highlighting the matches.
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
@ -28,6 +31,7 @@
var DEFAULT_MIN_CHARS = 2;
var DEFAULT_TOKEN_STYLE = "matchhighlight";
var DEFAULT_DELAY = 100;
var DEFAULT_WORDS_ONLY = false;
function State(options) {
if (typeof options == "object") {
@ -35,10 +39,12 @@
this.style = options.style;
this.showToken = options.showToken;
this.delay = options.delay;
this.wordsOnly = options.wordsOnly;
}
if (this.style == null) this.style = DEFAULT_TOKEN_STYLE;
if (this.minChars == null) this.minChars = DEFAULT_MIN_CHARS;
if (this.delay == null) this.delay = DEFAULT_DELAY;
if (this.wordsOnly == null) this.wordsOnly = DEFAULT_WORDS_ONLY;
this.overlay = this.timeout = null;
}
@ -81,12 +87,30 @@
}
var from = cm.getCursor("from"), to = cm.getCursor("to");
if (from.line != to.line) return;
if (state.wordsOnly && !isWord(cm, from, to)) return;
var selection = cm.getRange(from, to).replace(/^\s+|\s+$/g, "");
if (selection.length >= state.minChars)
cm.addOverlay(state.overlay = makeOverlay(selection, false, state.style));
});
}
function isWord(cm, from, to) {
var str = cm.getRange(from, to);
if (str.match(/^\w+$/) !== null) {
if (from.ch > 0) {
var pos = {line: from.line, ch: from.ch - 1};
var chr = cm.getRange(pos, from);
if (chr.match(/\W/) === null) return false;
}
if (to.ch < cm.getLine(from.line).length) {
var pos = {line: to.line, ch: to.ch + 1};
var chr = cm.getRange(to, pos);
if (chr.match(/\W/) === null) return false;
}
return true;
} else return false;
}
function boundariesAround(stream, re) {
return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) &&
(stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos)));

137
devtools/client/sourceeditor/codemirror/addon/search/search.js поставляемый Normal file → Executable file
Просмотреть файл

@ -18,6 +18,7 @@
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function searchOverlay(query, caseInsensitive) {
if (typeof query == "string")
query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
@ -39,39 +40,78 @@
}
function SearchState() {
this.posFrom = this.posTo = this.query = null;
this.posFrom = this.posTo = this.lastQuery = this.query = null;
this.overlay = null;
}
function getSearchState(cm) {
return cm.state.search || (cm.state.search = new SearchState());
}
function queryCaseInsensitive(query) {
return typeof query == "string" && query == query.toLowerCase();
}
function getSearchCursor(cm, query, pos) {
// Heuristic: if the query string is all lowercase, do a case insensitive search.
return cm.getSearchCursor(query, pos, queryCaseInsensitive(query));
}
function persistentDialog(cm, text, deflt, f) {
cm.openDialog(text, f, {
value: deflt,
selectValueOnOpen: true,
closeOnEnter: false,
onClose: function() { clearSearch(cm); }
});
}
function dialog(cm, text, shortText, deflt, f) {
if (cm.openDialog) cm.openDialog(text, f, {value: deflt});
if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
else f(prompt(shortText, deflt));
}
function confirmDialog(cm, text, shortText, fs) {
if (cm.openConfirm) cm.openConfirm(text, fs);
else if (confirm(shortText)) fs[0]();
}
function parseString(string) {
return string.replace(/\\(.)/g, function(_, ch) {
if (ch == "n") return "\n"
if (ch == "r") return "\r"
return ch
})
}
function parseQuery(query) {
var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
if (isRE) {
query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i");
if (query.test("")) query = /x^/;
} else if (query == "") {
query = /x^/;
try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); }
catch(e) {} // Not a regular expression after all, do a string search
} else {
query = parseString(query)
}
if (typeof query == "string" ? query == "" : query.test(""))
query = /x^/;
return query;
}
var queryDialog;
function doSearch(cm, rev) {
function startSearch(cm, state, query) {
state.queryText = query;
state.query = parseQuery(query);
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
cm.addOverlay(state.overlay);
if (cm.showMatchesOnScrollbar) {
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
}
}
function doSearch(cm, rev, persistent) {
if (!queryDialog) {
let doc = cm.getWrapperElement().ownerDocument;
let inp = doc.createElement("input");
@ -87,21 +127,37 @@
queryDialog.appendChild(inp);
queryDialog.style.display = "flex";
}
var state = getSearchState(cm);
if (state.query) return findNext(cm, rev);
dialog(cm, queryDialog, "Search for:", cm.getSelection(), function(query) {
cm.operation(function() {
if (!query || state.query) return;
state.query = parseQuery(query);
cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
cm.addOverlay(state.overlay);
state.posFrom = state.posTo = cm.getCursor();
findNext(cm, rev);
var q = cm.getSelection() || state.lastQuery;
if (persistent && cm.openDialog) {
var hiding = null
persistentDialog(cm, queryDialog, q, function(query, event) {
CodeMirror.e_stop(event);
if (!query) return;
if (query != state.queryText) startSearch(cm, state, query);
if (hiding) hiding.style.opacity = 1
findNext(cm, event.shiftKey, function(_, to) {
var dialog
if (to.line < 3 && document.querySelector &&
(dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) &&
dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top)
(hiding = dialog).style.opacity = .4
})
});
});
} else {
dialog(cm, queryDialog, "Search for:", q, function(query) {
if (query && !state.query) cm.operation(function() {
startSearch(cm, state, query);
state.posFrom = state.posTo = cm.getCursor();
findNext(cm, rev);
});
});
}
}
function findNext(cm, rev) {cm.operation(function() {
function findNext(cm, rev, callback) {cm.operation(function() {
var state = getSearchState(cm);
var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
if (!cursor.find(rev)) {
@ -109,34 +165,47 @@
if (!cursor.find(rev)) return;
}
cm.setSelection(cursor.from(), cursor.to());
cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
state.posFrom = cursor.from(); state.posTo = cursor.to();
if (callback) callback(cursor.from(), cursor.to())
});}
function clearSearch(cm) {cm.operation(function() {
var state = getSearchState(cm);
state.lastQuery = state.query;
if (!state.query) return;
state.query = null;
state.query = state.queryText = null;
cm.removeOverlay(state.overlay);
if (state.annotate) { state.annotate.clear(); state.annotate = null; }
});}
var replaceQueryDialog =
'Replace: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
var replacementQueryDialog = 'With: <input type="text" style="width: 10em"/>';
var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
' <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
var replacementQueryDialog = 'With: <input type="text" style="width: 10em" class="CodeMirror-search-field"/>';
var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>All</button> <button>Stop</button>";
function replaceAll(cm, query, text) {
cm.operation(function() {
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
if (typeof query != "string") {
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
} else cursor.replace(text);
}
});
}
function replace(cm, all) {
dialog(cm, replaceQueryDialog, "Replace:", cm.getSelection(), function(query) {
if (cm.getOption("readOnly")) return;
var query = cm.getSelection() || getSearchState(cm).lastQuery;
var dialogText = all ? "Replace all:" : "Replace:"
dialog(cm, dialogText + replaceQueryDialog, dialogText, query, function(query) {
if (!query) return;
query = parseQuery(query);
dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) {
text = parseString(text)
if (all) {
cm.operation(function() {
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
if (typeof query != "string") {
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
} else cursor.replace(text);
}
});
replaceAll(cm, query, text)
} else {
clearSearch(cm);
var cursor = getSearchCursor(cm, query, cm.getCursor());
@ -150,7 +219,8 @@
cm.setSelection(cursor.from(), cursor.to());
cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
confirmDialog(cm, doReplaceConfirm, "Replace?",
[function() {doReplace(match);}, advance]);
[function() {doReplace(match);}, advance,
function() {replaceAll(cm, query, text)}]);
};
var doReplace = function(match) {
cursor.replace(typeof query == "string" ? text :
@ -164,6 +234,7 @@
}
CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);};
CodeMirror.commands.findNext = doSearch;
CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
CodeMirror.commands.clearSearch = clearSearch;

10
devtools/client/sourceeditor/codemirror/addon/search/searchcursor.js поставляемый Normal file → Executable file
Просмотреть файл

@ -107,7 +107,7 @@
var from = Pos(pos.line, cut);
for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln)
if (target[i] != fold(doc.getLine(ln))) return;
if (doc.getLine(ln).slice(0, origTarget[last].length) != target[last]) return;
if (fold(doc.getLine(ln).slice(0, origTarget[last].length)) != target[last]) return;
return {from: from, to: Pos(ln, origTarget[last].length)};
}
};
@ -148,10 +148,10 @@
from: function() {if (this.atOccurrence) return this.pos.from;},
to: function() {if (this.atOccurrence) return this.pos.to;},
replace: function(newText) {
replace: function(newText, origin) {
if (!this.atOccurrence) return;
var lines = CodeMirror.splitLines(newText);
this.doc.replaceRange(lines, this.pos.from, this.pos.to);
this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin);
this.pos.to = Pos(this.pos.from.line + lines.length - 1,
lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0));
}
@ -177,9 +177,9 @@
});
CodeMirror.defineExtension("selectMatches", function(query, caseFold) {
var ranges = [], next;
var ranges = [];
var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold);
while (next = cur.findNext()) {
while (cur.findNext()) {
if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break;
ranges.push({anchor: cur.from(), head: cur.to()});
}

4
devtools/client/sourceeditor/codemirror/addon/selection/active-line.js поставляемый Normal file → Executable file
Просмотреть файл

@ -49,7 +49,9 @@
function updateActiveLines(cm, ranges) {
var active = [];
for (var i = 0; i < ranges.length; i++) {
var line = cm.getLineHandleVisualStart(ranges[i].head.line);
var range = ranges[i];
if (!range.empty()) continue;
var line = cm.getLineHandleVisualStart(range.head.line);
if (active[active.length - 1] != line) active.push(line);
}
if (sameArray(cm.state.activeLines, active)) return;

1
devtools/client/sourceeditor/codemirror/addon/tern/tern.css поставляемый Normal file → Executable file
Просмотреть файл

@ -1,6 +1,7 @@
.CodeMirror-Tern-completion {
padding-left: 22px;
position: relative;
line-height: 1.5;
}
.CodeMirror-Tern-completion:before {
position: absolute;

64
devtools/client/sourceeditor/codemirror/addon/tern/tern.js поставляемый Normal file → Executable file
Просмотреть файл

@ -59,6 +59,7 @@
this.options = options || {};
var plugins = this.options.plugins || (this.options.plugins = {});
if (!plugins.doc_comment) plugins.doc_comment = true;
this.docs = Object.create(null);
if (this.options.useWorker) {
this.server = new WorkerServer(this);
} else {
@ -69,7 +70,6 @@
plugins: plugins
});
}
this.docs = Object.create(null);
this.trackChange = function(doc, change) { trackChange(self, doc, change); };
this.cachedArgHints = null;
@ -106,7 +106,9 @@
cm.showHint({hint: this.getHint});
},
showType: function(cm, pos, cb) { showType(this, cm, pos, cb); },
showType: function(cm, pos, c) { showContextInfo(this, cm, pos, "type", c); },
showDocs: function(cm, pos, c) { showContextInfo(this, cm, pos, "documentation", c); },
updateArgHints: function(cm) { updateArgHints(this, cm); },
@ -122,12 +124,21 @@
var self = this;
var doc = findDoc(this, cm.getDoc());
var request = buildRequest(this, doc, query, pos);
var extraOptions = request.query && this.options.queryOptions && this.options.queryOptions[request.query.type]
if (extraOptions) for (var prop in extraOptions) request.query[prop] = extraOptions[prop];
this.server.request(request, function (error, data) {
if (!error && self.options.responseFilter)
data = self.options.responseFilter(doc, query, request, error, data);
c(error, data);
});
},
destroy: function () {
if (this.worker) {
this.worker.terminate();
this.worker = null;
}
}
};
@ -205,7 +216,7 @@
var completion = data.completions[i], className = typeToIcon(completion.type);
if (data.guess) className += " " + cls + "guess";
completions.push({text: completion.name + after,
displayText: completion.name,
displayText: completion.displayName || completion.name,
className: className,
data: completion});
}
@ -239,8 +250,8 @@
// Type queries
function showType(ts, cm, pos, cb) {
ts.request(cm, "type", function(error, data) {
function showContextInfo(ts, cm, pos, queryName, c) {
ts.request(cm, queryName, function(error, data) {
if (error) return showError(ts, cm, error);
if (ts.options.typeTip) {
var tip = ts.options.typeTip(data);
@ -250,11 +261,13 @@
tip.appendChild(document.createTextNode(" — " + data.doc));
if (data.url) {
tip.appendChild(document.createTextNode(" "));
tip.appendChild(elt("a", null, "[docs]")).href = data.url;
var child = tip.appendChild(elt("a", null, "[docs]"));
child.href = data.url;
child.target = "_blank";
}
}
tempTooltip(cm, tip);
if (cb) cb();
tempTooltip(cm, tip, ts);
if (c) c();
}, pos);
}
@ -431,8 +444,8 @@
function atInterestingExpression(cm) {
var pos = cm.getCursor("end"), tok = cm.getTokenAt(pos);
if (tok.start < pos.ch && (tok.type == "comment" || tok.type == "string")) return false;
return /\w/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1));
if (tok.start < pos.ch && tok.type == "comment") return false;
return /[\w)\]]/.test(cm.getLine(pos.line).slice(Math.max(pos.ch - 1, 0), pos.ch + 1));
}
// Variable renaming
@ -453,11 +466,12 @@
ts.request(cm, {type: "refs"}, function(error, data) {
if (error) return showError(ts, cm, error);
var ranges = [], cur = 0;
var curPos = cm.getCursor();
for (var i = 0; i < data.refs.length; i++) {
var ref = data.refs[i];
if (ref.file == name) {
ranges.push({anchor: ref.start, head: ref.end});
if (cmpPos(cur, ref.start) >= 0 && cmpPos(cur, ref.end) <= 0)
if (cmpPos(curPos, ref.start) >= 0 && cmpPos(curPos, ref.end) <= 0)
cur = ranges.length - 1;
}
}
@ -579,16 +593,34 @@
// Tooltips
function tempTooltip(cm, content) {
function tempTooltip(cm, content, ts) {
if (cm.state.ternTooltip) remove(cm.state.ternTooltip);
var where = cm.cursorCoords();
var tip = makeTooltip(where.right + 1, where.bottom, content);
var tip = cm.state.ternTooltip = makeTooltip(where.right + 1, where.bottom, content);
function maybeClear() {
old = true;
if (!mouseOnTip) clear();
}
function clear() {
cm.state.ternTooltip = null;
if (!tip.parentNode) return;
cm.off("cursorActivity", clear);
cm.off('blur', clear);
cm.off('scroll', clear);
fadeOut(tip);
}
setTimeout(clear, 1700);
var mouseOnTip = false, old = false;
CodeMirror.on(tip, "mousemove", function() { mouseOnTip = true; });
CodeMirror.on(tip, "mouseout", function(e) {
if (!CodeMirror.contains(tip, e.relatedTarget || e.toElement)) {
if (old) clear();
else mouseOnTip = false;
}
});
setTimeout(maybeClear, ts.options.hintDelay ? ts.options.hintDelay : 1700);
cm.on("cursorActivity", clear);
cm.on('blur', clear);
cm.on('scroll', clear);
}
function makeTooltip(x, y, content) {
@ -613,7 +645,7 @@
if (ts.options.showError)
ts.options.showError(cm, msg);
else
tempTooltip(cm, String(msg));
tempTooltip(cm, String(msg), ts);
}
function closeArgHints(ts) {
@ -629,7 +661,7 @@
// Worker wrapper
function WorkerServer(ts) {
var worker = new Worker(ts.options.workerScript);
var worker = ts.worker = new Worker(ts.options.workerScript);
worker.postMessage({type: "init",
defs: ts.options.defs,
plugins: ts.options.plugins,

82
devtools/client/sourceeditor/codemirror/keymap/emacs.js поставляемый Normal file → Executable file
Просмотреть файл

@ -132,8 +132,8 @@
};
}
function findEnd(cm, by, dir) {
var pos = cm.getCursor(), prefix = getPrefix(cm);
function findEnd(cm, pos, by, dir) {
var prefix = getPrefix(cm);
if (prefix < 0) { dir = -dir; prefix = -prefix; }
for (var i = 0; i < prefix; ++i) {
var newPos = by(cm, pos, dir);
@ -145,14 +145,31 @@
function move(by, dir) {
var f = function(cm) {
cm.extendSelection(findEnd(cm, by, dir));
cm.extendSelection(findEnd(cm, cm.getCursor(), by, dir));
};
f.motion = true;
return f;
}
function killTo(cm, by, dir) {
kill(cm, cm.getCursor(), findEnd(cm, by, dir), true);
var selections = cm.listSelections(), cursor;
var i = selections.length;
while (i--) {
cursor = selections[i].head;
kill(cm, cursor, findEnd(cm, cursor, by, dir), true);
}
}
function killRegion(cm) {
if (cm.somethingSelected()) {
var selections = cm.listSelections(), selection;
var i = selections.length;
while (i--) {
selection = selections[i];
kill(cm, selection.anchor, selection.head);
}
return true;
}
}
function addPrefix(cm, digit) {
@ -256,7 +273,7 @@
// Actual keymap
var keyMap = CodeMirror.keyMap.emacs = {
var keyMap = CodeMirror.keyMap.emacs = CodeMirror.normalizeKeyMap({
"Ctrl-W": function(cm) {kill(cm, cm.getCursor("start"), cm.getCursor("end"));},
"Ctrl-K": repeated(function(cm) {
var start = cm.getCursor(), end = cm.clipPos(Pos(start.line));
@ -283,9 +300,9 @@
"Ctrl-F": move(byChar, 1), "Ctrl-B": move(byChar, -1),
"Right": move(byChar, 1), "Left": move(byChar, -1),
"Ctrl-D": function(cm) { killTo(cm, byChar, 1); },
"Delete": function(cm) { killTo(cm, byChar, 1); },
"Delete": function(cm) { killRegion(cm) || killTo(cm, byChar, 1); },
"Ctrl-H": function(cm) { killTo(cm, byChar, -1); },
"Backspace": function(cm) { killTo(cm, byChar, -1); },
"Backspace": function(cm) { killRegion(cm) || killTo(cm, byChar, -1); },
"Alt-F": move(byWord, 1), "Alt-B": move(byWord, -1),
"Alt-D": function(cm) { killTo(cm, byWord, 1); },
@ -309,7 +326,8 @@
"Ctrl-Alt-F": move(byExpr, 1), "Ctrl-Alt-B": move(byExpr, -1),
"Shift-Ctrl-Alt-2": function(cm) {
cm.setSelection(findEnd(cm, byExpr, 1), cm.getCursor());
var cursor = cm.getCursor();
cm.setSelection(findEnd(cm, cursor, byExpr, 1), cursor);
},
"Ctrl-Alt-T": function(cm) {
var leftStart = byExpr(cm, cm.getCursor(), -1), leftEnd = byExpr(cm, leftStart, 1);
@ -353,43 +371,35 @@
"Alt-/": "autocomplete",
"Ctrl-J": "newlineAndIndent", "Enter": false, "Tab": "indentAuto",
"Alt-G": function(cm) {cm.setOption("keyMap", "emacs-Alt-G");},
"Ctrl-X": function(cm) {cm.setOption("keyMap", "emacs-Ctrl-X");},
"Ctrl-Q": function(cm) {cm.setOption("keyMap", "emacs-Ctrl-Q");},
"Ctrl-U": addPrefixMap
};
CodeMirror.keyMap["emacs-Ctrl-X"] = {
"Tab": function(cm) {
cm.indentSelection(getPrefix(cm, true) || cm.getOption("indentUnit"));
},
"Ctrl-X": function(cm) {
cm.setSelection(cm.getCursor("head"), cm.getCursor("anchor"));
},
"Ctrl-S": "save", "Ctrl-W": "save", "S": "saveAll", "F": "open", "U": repeated("undo"), "K": "close",
"Delete": function(cm) { kill(cm, cm.getCursor(), bySentence(cm, cm.getCursor(), 1), true); },
auto: "emacs", nofallthrough: true, disableInput: true
};
CodeMirror.keyMap["emacs-Alt-G"] = {
"G": function(cm) {
"Alt-G G": function(cm) {
var prefix = getPrefix(cm, true);
if (prefix != null && prefix > 0) return cm.setCursor(prefix - 1);
getInput(cm, "Goto line", function(str) {
var num;
if (str && !isNaN(num = Number(str)) && num == num|0 && num > 0)
if (str && !isNaN(num = Number(str)) && num == (num|0) && num > 0)
cm.setCursor(num - 1);
});
},
auto: "emacs", nofallthrough: true, disableInput: true
};
CodeMirror.keyMap["emacs-Ctrl-Q"] = {
"Tab": repeated("insertTab"),
auto: "emacs", nofallthrough: true
};
"Ctrl-X Tab": function(cm) {
cm.indentSelection(getPrefix(cm, true) || cm.getOption("indentUnit"));
},
"Ctrl-X Ctrl-X": function(cm) {
cm.setSelection(cm.getCursor("head"), cm.getCursor("anchor"));
},
"Ctrl-X Ctrl-S": "save",
"Ctrl-X Ctrl-W": "save",
"Ctrl-X S": "saveAll",
"Ctrl-X F": "open",
"Ctrl-X U": repeated("undo"),
"Ctrl-X K": "close",
"Ctrl-X Delete": function(cm) { kill(cm, cm.getCursor(), bySentence(cm, cm.getCursor(), 1), true); },
"Ctrl-X H": "selectAll",
"Ctrl-Q Tab": repeated("insertTab"),
"Ctrl-U": addPrefixMap
});
var prefixMap = {"Ctrl-G": clearPrefix};
function regPrefix(d) {

93
devtools/client/sourceeditor/codemirror/keymap/sublime.js поставляемый Normal file → Executable file
Просмотреть файл

@ -17,7 +17,8 @@
var map = CodeMirror.keyMap.sublime = {fallthrough: "default"};
var cmds = CodeMirror.commands;
var Pos = CodeMirror.Pos;
var ctrl = CodeMirror.keyMap["default"] == CodeMirror.keyMap.pcDefault ? "Ctrl-" : "Cmd-";
var mac = CodeMirror.keyMap["default"] == CodeMirror.keyMap.macDefault;
var ctrl = mac ? "Cmd-" : "Ctrl-";
// This is not exactly Sublime's algorithm. I couldn't make heads or tails of that.
function findPosSubword(doc, start, dir) {
@ -54,7 +55,9 @@
cmds[map["Alt-Left"] = "goSubwordLeft"] = function(cm) { moveSubword(cm, -1); };
cmds[map["Alt-Right"] = "goSubwordRight"] = function(cm) { moveSubword(cm, 1); };
cmds[map[ctrl + "Up"] = "scrollLineUp"] = function(cm) {
var scrollLineCombo = mac ? "Ctrl-Alt-" : "Ctrl-";
cmds[map[scrollLineCombo + "Up"] = "scrollLineUp"] = function(cm) {
var info = cm.getScrollInfo();
if (!cm.somethingSelected()) {
var visibleBottomLine = cm.lineAtHeight(info.top + info.clientHeight, "local");
@ -63,7 +66,7 @@
}
cm.scrollTo(null, info.top - cm.defaultTextHeight());
};
cmds[map[ctrl + "Down"] = "scrollLineDown"] = function(cm) {
cmds[map[scrollLineCombo + "Down"] = "scrollLineDown"] = function(cm) {
var info = cm.getScrollInfo();
if (!cm.somethingSelected()) {
var visibleTopLine = cm.lineAtHeight(info.top, "local")+1;
@ -186,7 +189,9 @@
});
};
cmds[map["Shift-" + ctrl + "Up"] = "swapLineUp"] = function(cm) {
var swapLineCombo = mac ? "Cmd-Ctrl-" : "Shift-Ctrl-";
cmds[map[swapLineCombo + "Up"] = "swapLineUp"] = function(cm) {
var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1, newSels = [];
for (var i = 0; i < ranges.length; i++) {
var range = ranges[i], from = range.from().line - 1, to = range.to().line;
@ -212,7 +217,7 @@
});
};
cmds[map["Shift-" + ctrl + "Down"] = "swapLineDown"] = function(cm) {
cmds[map[swapLineCombo + "Down"] = "swapLineDown"] = function(cm) {
var ranges = cm.listSelections(), linesToMove = [], at = cm.lastLine() + 1;
for (var i = ranges.length - 1; i >= 0; i--) {
var range = ranges[i], from = range.to().line + 1, to = range.from().line;
@ -383,9 +388,7 @@
map["Alt-Q"] = "wrapLines";
var mapK = CodeMirror.keyMap["sublime-Ctrl-K"] = {auto: "sublime", nofallthrough: true};
map[ctrl + "K"] = function(cm) {cm.setOption("keyMap", "sublime-Ctrl-K");};
var cK = ctrl + "K ";
function modifyWordOrSelection(cm, mod) {
cm.operation(function() {
@ -406,9 +409,30 @@
});
}
mapK[ctrl + "Backspace"] = "delLineLeft";
map[cK + ctrl + "Backspace"] = "delLineLeft";
cmds[mapK[ctrl + "K"] = "delLineRight"] = function(cm) {
cmds[map["Backspace"] = "smartBackspace"] = function(cm) {
if (cm.somethingSelected()) return CodeMirror.Pass;
var cursor = cm.getCursor();
var toStartOfLine = cm.getRange({line: cursor.line, ch: 0}, cursor);
var column = CodeMirror.countColumn(toStartOfLine, null, cm.getOption("tabSize"));
var indentUnit = cm.getOption("indentUnit");
if (toStartOfLine && !/\S/.test(toStartOfLine) && column % indentUnit == 0) {
var prevIndent = new Pos(cursor.line,
CodeMirror.findColumn(toStartOfLine, column - indentUnit, indentUnit));
// If no smart delete is happening (due to tab sizing) just do a regular delete
if (prevIndent.ch == cursor.ch) return CodeMirror.Pass;
return cm.replaceRange("", prevIndent, cursor, "+delete");
} else {
return CodeMirror.Pass;
}
};
cmds[map[cK + ctrl + "K"] = "delLineRight"] = function(cm) {
cm.operation(function() {
var ranges = cm.listSelections();
for (var i = ranges.length - 1; i >= 0; i--)
@ -417,22 +441,22 @@
});
};
cmds[mapK[ctrl + "U"] = "upcaseAtCursor"] = function(cm) {
cmds[map[cK + ctrl + "U"] = "upcaseAtCursor"] = function(cm) {
modifyWordOrSelection(cm, function(str) { return str.toUpperCase(); });
};
cmds[mapK[ctrl + "L"] = "downcaseAtCursor"] = function(cm) {
cmds[map[cK + ctrl + "L"] = "downcaseAtCursor"] = function(cm) {
modifyWordOrSelection(cm, function(str) { return str.toLowerCase(); });
};
cmds[mapK[ctrl + "Space"] = "setSublimeMark"] = function(cm) {
cmds[map[cK + ctrl + "Space"] = "setSublimeMark"] = function(cm) {
if (cm.state.sublimeMark) cm.state.sublimeMark.clear();
cm.state.sublimeMark = cm.setBookmark(cm.getCursor());
};
cmds[mapK[ctrl + "A"] = "selectToSublimeMark"] = function(cm) {
cmds[map[cK + ctrl + "A"] = "selectToSublimeMark"] = function(cm) {
var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) cm.setSelection(cm.getCursor(), found);
};
cmds[mapK[ctrl + "W"] = "deleteToSublimeMark"] = function(cm) {
cmds[map[cK + ctrl + "W"] = "deleteToSublimeMark"] = function(cm) {
var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) {
var from = cm.getCursor(), to = found;
@ -441,7 +465,7 @@
cm.replaceRange("", from, to);
}
};
cmds[mapK[ctrl + "X"] = "swapWithSublimeMark"] = function(cm) {
cmds[map[cK + ctrl + "X"] = "swapWithSublimeMark"] = function(cm) {
var found = cm.state.sublimeMark && cm.state.sublimeMark.find();
if (found) {
cm.state.sublimeMark.clear();
@ -449,13 +473,13 @@
cm.setCursor(found);
}
};
cmds[mapK[ctrl + "Y"] = "sublimeYank"] = function(cm) {
cmds[map[cK + ctrl + "Y"] = "sublimeYank"] = function(cm) {
if (cm.state.sublimeKilled != null)
cm.replaceSelection(cm.state.sublimeKilled, null, "paste");
};
mapK[ctrl + "G"] = "clearBookmarks";
cmds[mapK[ctrl + "C"] = "showInCenter"] = function(cm) {
map[cK + ctrl + "G"] = "clearBookmarks";
cmds[map[cK + ctrl + "C"] = "showInCenter"] = function(cm) {
var pos = cm.cursorCoords(null, "local");
cm.scrollTo(null, (pos.top + pos.bottom) / 2 - cm.getScrollInfo().clientHeight / 2);
};
@ -481,7 +505,7 @@
});
};
function findAndGoTo(cm, forward) {
function getTarget(cm) {
var from = cm.getCursor("from"), to = cm.getCursor("to");
if (CodeMirror.cmpPos(from, to) == 0) {
var word = wordAt(cm, from);
@ -489,9 +513,14 @@
from = word.from;
to = word.to;
}
return {from: from, to: to, query: cm.getRange(from, to), word: word};
}
var query = cm.getRange(from, to);
var cur = cm.getSearchCursor(query, forward ? to : from);
function findAndGoTo(cm, forward) {
var target = getTarget(cm);
if (!target) return;
var query = target.query;
var cur = cm.getSearchCursor(query, forward ? target.to : target.from);
if (forward ? cur.findNext() : cur.findPrevious()) {
cm.setSelection(cur.from(), cur.to());
@ -500,16 +529,29 @@
: cm.clipPos(Pos(cm.lastLine())));
if (forward ? cur.findNext() : cur.findPrevious())
cm.setSelection(cur.from(), cur.to());
else if (word)
cm.setSelection(from, to);
else if (target.word)
cm.setSelection(target.from, target.to);
}
};
cmds[map[ctrl + "F3"] = "findUnder"] = function(cm) { findAndGoTo(cm, true); };
cmds[map["Shift-" + ctrl + "F3"] = "findUnderPrevious"] = function(cm) { findAndGoTo(cm,false); };
cmds[map["Alt-F3"] = "findAllUnder"] = function(cm) {
var target = getTarget(cm);
if (!target) return;
var cur = cm.getSearchCursor(target.query);
var matches = [];
var primaryIndex = -1;
while (cur.findNext()) {
matches.push({anchor: cur.from(), head: cur.to()});
if (cur.from().line <= target.from.line && cur.from().ch <= target.from.ch)
primaryIndex++;
}
cm.setSelections(matches, primaryIndex);
};
map["Shift-" + ctrl + "["] = "fold";
map["Shift-" + ctrl + "]"] = "unfold";
mapK[ctrl + "0"] = mapK[ctrl + "j"] = "unfoldAll";
map[cK + ctrl + "0"] = map[cK + ctrl + "j"] = "unfoldAll";
map[ctrl + "I"] = "findIncremental";
map["Shift-" + ctrl + "I"] = "findIncrementalReverse";
@ -517,4 +559,5 @@
map["F3"] = "findNext";
map["Shift-F3"] = "findPrev";
CodeMirror.normalizeKeyMap(map);
});

3019
devtools/client/sourceeditor/codemirror/keymap/vim.js поставляемый Normal file → Executable file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

140
devtools/client/sourceeditor/codemirror/lib/codemirror.css поставляемый Normal file → Executable file
Просмотреть файл

@ -4,10 +4,7 @@
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: 300px;
}
.CodeMirror-scroll {
/* Set scrolling behaviour here */
overflow: auto;
color: black;
}
/* PADDING */
@ -36,28 +33,60 @@
min-width: 20px;
text-align: right;
color: #999;
-moz-box-sizing: content-box;
box-sizing: content-box;
white-space: nowrap;
}
.CodeMirror-guttermarker { color: black; }
.CodeMirror-guttermarker-subtle { color: #999; }
/* CURSOR */
.CodeMirror div.CodeMirror-cursor {
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0;
background: #7e7;
}
/* Can style cursor different in overwrite (non-insert) mode */
div.CodeMirror-overwrite div.CodeMirror-cursor {}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-tab { display: inline-block; }
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-moz-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@-webkit-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror-overwrite .CodeMirror-cursor {}
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-ruler {
border-left: 1px solid #ccc;
@ -66,6 +95,15 @@ div.CodeMirror-overwrite div.CodeMirror-cursor {}
/* DEFAULT THEME */
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
@ -85,22 +123,19 @@ div.CodeMirror-overwrite div.CodeMirror-cursor {}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
.CodeMirror-composing { border-bottom: 2px solid; }
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */
@ -109,14 +144,13 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
the editor. You probably shouldn't touch them. */
.CodeMirror {
line-height: 1;
position: relative;
overflow: hidden;
background: white;
color: black;
}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
@ -124,14 +158,10 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
@ -161,29 +191,42 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
padding-bottom: 30px;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
-moz-box-sizing: content-box;
box-sizing: content-box;
padding-bottom: 30px;
margin-bottom: -32px;
display: inline-block;
margin-bottom: -30px;
/* Hack to make IE7 behave */
*zoom:1;
*display:inline;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0; bottom: 0;
z-index: 4;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-gutter-wrapper {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.CodeMirror-lines {
cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
}
.CodeMirror pre {
/* Reset some styles that the rest of the page might have set */
@ -200,6 +243,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
@ -221,8 +265,18 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-widget {}
.CodeMirror-wrap .CodeMirror-scroll {
overflow-x: hidden;
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-measure {
@ -232,19 +286,19 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
overflow: hidden;
visibility: hidden;
}
.CodeMirror-measure pre { position: static; }
.CodeMirror div.CodeMirror-cursor {
position: absolute;
border-right: none;
width: 0;
}
.CodeMirror-cursor { position: absolute; }
.CodeMirror-measure pre { position: static; }
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 1;
z-index: 3;
}
div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
@ -252,6 +306,8 @@ div.CodeMirror-cursors {
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching {
background: #ffa;
@ -270,3 +326,9 @@ div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
.cm-tab-wrap-hack:after { content: ''; }
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }

3404
devtools/client/sourceeditor/codemirror/lib/codemirror.js поставляемый Normal file → Executable file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

288
devtools/client/sourceeditor/codemirror/mode/clike.js поставляемый Normal file → Executable file
Просмотреть файл

@ -16,14 +16,19 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
dontAlignCalls = parserConfig.dontAlignCalls,
keywords = parserConfig.keywords || {},
types = parserConfig.types || {},
builtin = parserConfig.builtin || {},
blockKeywords = parserConfig.blockKeywords || {},
defKeywords = parserConfig.defKeywords || {},
atoms = parserConfig.atoms || {},
hooks = parserConfig.hooks || {},
multiLineStrings = parserConfig.multiLineStrings;
multiLineStrings = parserConfig.multiLineStrings,
indentStatements = parserConfig.indentStatements !== false,
indentSwitch = parserConfig.indentSwitch !== false,
namespaceSeparator = parserConfig.namespaceSeparator;
var isOperatorChar = /[+\-*&%=<>!?|\/]/;
var curPunc;
var curPunc, isDefKeyword;
function tokenBase(stream, state) {
var ch = stream.next();
@ -57,12 +62,17 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
stream.eatWhile(isOperatorChar);
return "operator";
}
stream.eatWhile(/[\w\$_]/);
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
if (namespaceSeparator) while (stream.match(namespaceSeparator))
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
var cur = stream.current();
if (keywords.propertyIsEnumerable(cur)) {
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
if (defKeywords.propertyIsEnumerable(cur)) isDefKeyword = true;
return "keyword";
}
if (types.propertyIsEnumerable(cur)) return "variable-3";
if (builtin.propertyIsEnumerable(cur)) {
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
return "builtin";
@ -103,9 +113,12 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
this.align = align;
this.prev = prev;
}
function isStatement(type) {
return type == "statement" || type == "switchstatement" || type == "namespace";
}
function pushContext(state, col, type) {
var indent = state.indented;
if (state.context && state.context.type == "statement")
if (state.context && isStatement(state.context.type) && !isStatement(type))
indent = state.context.indented;
return state.context = new Context(indent, col, type, null, state.context);
}
@ -116,6 +129,19 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
return state.context = state.context.prev;
}
function typeBefore(stream, state) {
if (state.prevToken == "variable" || state.prevToken == "variable-3") return true;
if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, stream.start))) return true;
}
function isTopScope(context) {
for (;;) {
if (!context || context.type == "top") return true;
if (context.type == "}" && context.prev.type != "namespace") return false;
context = context.prev;
}
}
// Interface
return {
@ -124,7 +150,8 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
tokenize: null,
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
indented: 0,
startOfLine: true
startOfLine: true,
prevToken: null
};
},
@ -136,39 +163,69 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
state.startOfLine = true;
}
if (stream.eatSpace()) return null;
curPunc = null;
curPunc = isDefKeyword = null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment" || style == "meta") return style;
if (ctx.align == null) ctx.align = true;
if ((curPunc == ";" || curPunc == ":" || curPunc == ",") && ctx.type == "statement") popContext(state);
if ((curPunc == ";" || curPunc == ":" || curPunc == ","))
while (isStatement(state.context.type)) popContext(state);
else if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "}") {
while (ctx.type == "statement") ctx = popContext(state);
while (isStatement(ctx.type)) ctx = popContext(state);
if (ctx.type == "}") ctx = popContext(state);
while (ctx.type == "statement") ctx = popContext(state);
while (isStatement(ctx.type)) ctx = popContext(state);
}
else if (curPunc == ctx.type) popContext(state);
else if (((ctx.type == "}" || ctx.type == "top") && curPunc != ';') || (ctx.type == "statement" && curPunc == "newstatement"))
pushContext(state, stream.column(), "statement");
else if (indentStatements &&
(((ctx.type == "}" || ctx.type == "top") && curPunc != ";") ||
(isStatement(ctx.type) && curPunc == "newstatement"))) {
var type = "statement";
if (curPunc == "newstatement" && indentSwitch && stream.current() == "switch")
type = "switchstatement";
else if (style == "keyword" && stream.current() == "namespace")
type = "namespace";
pushContext(state, stream.column(), type);
}
if (style == "variable" &&
((state.prevToken == "def" ||
(parserConfig.typeFirstDefinitions && typeBefore(stream, state) &&
isTopScope(state.context) && stream.match(/^\s*\(/, false)))))
style = "def";
if (hooks.token) {
var result = hooks.token(stream, state, style);
if (result !== undefined) style = result;
}
if (style == "def" && parserConfig.styleDefs === false) style = "variable";
state.startOfLine = false;
state.prevToken = isDefKeyword ? "def" : style || curPunc;
return style;
},
indent: function(state, textAfter) {
if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
if (isStatement(ctx.type) && firstChar == "}") ctx = ctx.prev;
var closing = firstChar == ctx.type;
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
else if (ctx.align && (!dontAlignCalls || ctx.type != ")")) return ctx.column + (closing ? 0 : 1);
else if (ctx.type == ")" && !closing) return ctx.indented + statementIndentUnit;
else return ctx.indented + (closing ? 0 : indentUnit);
var switchBlock = ctx.prev && ctx.prev.type == "switchstatement";
if (isStatement(ctx.type))
return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
return ctx.column + (closing ? 0 : 1);
if (ctx.type == ")" && !closing)
return ctx.indented + statementIndentUnit;
return ctx.indented + (closing ? 0 : indentUnit) +
(!closing && switchBlock && !/^(?:case|default)\b/.test(textAfter) ? indentUnit : 0);
},
electricChars: "{}",
electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/,
blockCommentStart: "/*",
blockCommentEnd: "*/",
lineComment: "//",
@ -181,9 +238,10 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
var cKeywords = "auto if break int case long char register continue return default short do sizeof " +
"double static else struct entry switch extern typedef float union for unsigned " +
"goto while enum void const signed volatile";
var cKeywords = "auto if break case register continue return default do sizeof " +
"static else struct switch extern typedef float union for " +
"goto while enum const volatile";
var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t";
function cppHook(stream, state) {
if (!state.startOfLine) return false;
@ -203,11 +261,21 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
return "meta";
}
function pointerHook(_stream, state) {
if (state.prevToken == "variable-3") return "variable-3";
return false;
}
function cpp14Literal(stream) {
stream.eatWhile(/[\w\.']/);
return "number";
}
function cpp11StringHook(stream, state) {
stream.backUp(1);
// Raw strings.
if (stream.match(/(R|u8R|uR|UR|LR)/)) {
var match = stream.match(/"(.{0,16})\(/);
var match = stream.match(/"([^\s\\()]{0,16})\(/);
if (!match) {
return false;
}
@ -227,6 +295,11 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
return false;
}
function cppLooksLikeConstructor(word) {
var lastTwo = /(\w+)::(\w+)$/.exec(word);
return lastTwo && lastTwo[1] == lastTwo[2];
}
// C#-style strings where "" escapes a quote.
function tokenAtString(stream, state) {
var next;
@ -242,13 +315,13 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
// C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where
// <delim> can be a string up to 16 characters long.
function tokenRawString(stream, state) {
var closingSequence = new RegExp(".*?\\)" + state.cpp11RawStringDelim + '"');
var match = stream.match(closingSequence);
if (match) {
// Escape characters that have special regex meanings.
var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&');
var match = stream.match(new RegExp(".*?\\)" + delim + '"'));
if (match)
state.tokenize = null;
} else {
else
stream.skipToEnd();
}
return "string";
}
@ -260,6 +333,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
words.push(prop);
}
add(mode.keywords);
add(mode.types);
add(mode.builtin);
add(mode.atoms);
if (words.length) {
@ -274,38 +348,70 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
name: "clike",
keywords: words(cKeywords),
types: words(cTypes + " bool _Complex _Bool float_t double_t intptr_t intmax_t " +
"int8_t int16_t int32_t int64_t uintptr_t uintmax_t uint8_t uint16_t " +
"uint32_t uint64_t"),
blockKeywords: words("case do else for if switch while struct"),
atoms: words("null"),
hooks: {"#": cppHook},
defKeywords: words("struct"),
typeFirstDefinitions: true,
atoms: words("null true false"),
hooks: {"#": cppHook, "*": pointerHook},
modeProps: {fold: ["brace", "include"]}
});
def(["text/x-c++src", "text/x-c++hdr"], {
name: "clike",
keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try bool explicit new " +
keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try explicit new " +
"static_cast typeid catch operator template typename class friend private " +
"this using const_cast inline public throw virtual delete mutable protected " +
"wchar_t alignas alignof constexpr decltype nullptr noexcept thread_local final " +
"alignas alignof constexpr decltype nullptr noexcept thread_local final " +
"static_assert override"),
types: words(cTypes + " bool wchar_t"),
blockKeywords: words("catch class do else finally for if struct switch try while"),
defKeywords: words("class namespace struct enum union"),
typeFirstDefinitions: true,
atoms: words("true false null"),
hooks: {
"#": cppHook,
"*": pointerHook,
"u": cpp11StringHook,
"U": cpp11StringHook,
"L": cpp11StringHook,
"R": cpp11StringHook
"R": cpp11StringHook,
"0": cpp14Literal,
"1": cpp14Literal,
"2": cpp14Literal,
"3": cpp14Literal,
"4": cpp14Literal,
"5": cpp14Literal,
"6": cpp14Literal,
"7": cpp14Literal,
"8": cpp14Literal,
"9": cpp14Literal,
token: function(stream, state, style) {
if (style == "variable" && stream.peek() == "(" &&
(state.prevToken == ";" || state.prevToken == null ||
state.prevToken == "}") &&
cppLooksLikeConstructor(stream.current()))
return "def";
}
},
namespaceSeparator: "::",
modeProps: {fold: ["brace", "include"]}
});
def("text/x-java", {
name: "clike",
keywords: words("abstract assert boolean break byte case catch char class const continue default " +
"do double else enum extends final finally float for goto if implements import " +
"instanceof int interface long native new package private protected public " +
"return short static strictfp super switch synchronized this throw throws transient " +
"try void volatile while"),
keywords: words("abstract assert break case catch class const continue default " +
"do else enum extends final finally float for goto if implements import " +
"instanceof interface native new package private protected public " +
"return static strictfp super switch synchronized this throw throws transient " +
"try volatile while"),
types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " +
"Integer Long Number Object Short String StringBuffer StringBuilder Void"),
blockKeywords: words("catch class do else finally for if switch try while"),
defKeywords: words("class interface package enum"),
typeFirstDefinitions: true,
atoms: words("true false null"),
hooks: {
"@": function(stream) {
@ -315,20 +421,23 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
},
modeProps: {fold: ["brace", "import"]}
});
def("text/x-csharp", {
name: "clike",
keywords: words("abstract as base break case catch checked class const continue" +
keywords: words("abstract as async await base break case catch checked class const continue" +
" default delegate do else enum event explicit extern finally fixed for" +
" foreach goto if implicit in interface internal is lock namespace new" +
" operator out override params private protected public readonly ref return sealed" +
" sizeof stackalloc static struct switch this throw try typeof unchecked" +
" unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
" global group into join let orderby partial remove select set value var yield"),
types: words("Action Boolean Byte Char DateTime DateTimeOffset Decimal Double Func" +
" Guid Int16 Int32 Int64 Object SByte Single String Task TimeSpan UInt16 UInt32" +
" UInt64 bool byte char decimal double short int long object" +
" sbyte float string ushort uint ulong"),
blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
builtin: words("Boolean Byte Char DateTime DateTimeOffset Decimal Double" +
" Guid Int16 Int32 Int64 Object SByte Single String TimeSpan UInt16 UInt32" +
" UInt64 bool byte char decimal double short int long object" +
" sbyte float string ushort uint ulong"),
defKeywords: words("class interface namespace struct var"),
typeFirstDefinitions: true,
atoms: words("true false null"),
hooks: {
"@": function(stream, state) {
@ -341,6 +450,19 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
}
}
});
function tokenTripleString(stream, state) {
var escaped = false;
while (!stream.eol()) {
if (!escaped && stream.match('"""')) {
state.tokenize = null;
break;
}
escaped = stream.next() == "\\" && !escaped;
}
return "string";
}
def("text/x-scala", {
name: "clike",
keywords: words(
@ -348,51 +470,67 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
/* scala */
"abstract case catch class def do else extends false final finally for forSome if " +
"implicit import lazy match new null object override package private protected return " +
"sealed super this throw trait try trye type val var while with yield _ : = => <- <: " +
"sealed super this throw trait try type val var while with yield _ : = => <- <: " +
"<% >: # @ " +
/* package scala */
"assert assume require print println printf readLine readBoolean readByte readShort " +
"readChar readInt readLong readFloat readDouble " +
":: #:: "
),
types: words(
"AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
"Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable " +
"Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
"Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
"StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector :: #:: " +
"StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector " +
/* package java.lang */
"Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
"Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
),
multiLineStrings: true,
blockKeywords: words("catch class do else finally for forSome if match switch try while"),
defKeywords: words("class def object package trait type val var"),
atoms: words("true false null"),
indentStatements: false,
indentSwitch: false,
hooks: {
"@": function(stream) {
stream.eatWhile(/[\w\$_]/);
return "meta";
},
'"': function(stream, state) {
if (!stream.match('""')) return false;
state.tokenize = tokenTripleString;
return state.tokenize(stream, state);
},
"'": function(stream) {
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
return "atom";
}
}
},
modeProps: {closeBrackets: {triples: '"'}}
});
def(["x-shader/x-vertex", "x-shader/x-fragment"], {
name: "clike",
keywords: words("float int bool void " +
"vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
"mat2 mat3 mat4 " +
"sampler1D sampler2D sampler3D samplerCube " +
"sampler1DShadow sampler2DShadow" +
keywords: words("sampler1D sampler2D sampler3D samplerCube " +
"sampler1DShadow sampler2DShadow " +
"const attribute uniform varying " +
"break continue discard return " +
"for while do if else struct " +
"in out inout"),
types: words("float int bool void " +
"vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
"mat2 mat3 mat4"),
blockKeywords: words("for while do if else struct"),
builtin: words("radians degrees sin cos tan asin acos atan " +
"pow exp log exp2 sqrt inversesqrt " +
"abs sign floor ceil fract mod min max clamp mix step smootstep " +
"abs sign floor ceil fract mod min max clamp mix step smoothstep " +
"length distance dot cross normalize ftransform faceforward " +
"reflect refract matrixCompMult " +
"lessThan lessThanEqual greaterThan greaterThanEqual " +
@ -409,12 +547,12 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
"gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
"gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
"gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
"gl_FogCoord " +
"gl_FogCoord gl_PointCoord " +
"gl_Position gl_PointSize gl_ClipVertex " +
"gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
"gl_TexCoord gl_FogFragCoord " +
"gl_FragCoord gl_FrontFacing " +
"gl_FragColor gl_FragData gl_FragDepth " +
"gl_FragData gl_FragDepth " +
"gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
"gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
"gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
@ -432,6 +570,48 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
"gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
"gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
"gl_MaxDrawBuffers"),
indentSwitch: false,
hooks: {"#": cppHook},
modeProps: {fold: ["brace", "include"]}
});
def("text/x-nesc", {
name: "clike",
keywords: words(cKeywords + "as atomic async call command component components configuration event generic " +
"implementation includes interface module new norace nx_struct nx_union post provides " +
"signal task uses abstract extends"),
types: words(cTypes),
blockKeywords: words("case do else for if switch while struct"),
atoms: words("null true false"),
hooks: {"#": cppHook},
modeProps: {fold: ["brace", "include"]}
});
def("text/x-objectivec", {
name: "clike",
keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginery BOOL Class bycopy byref id IMP in " +
"inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"),
types: words(cTypes),
atoms: words("YES NO NULL NILL ON OFF true false"),
hooks: {
"@": function(stream) {
stream.eatWhile(/[\w\$]/);
return "keyword";
},
"#": cppHook
},
modeProps: {fold: "brace"}
});
def("text/x-squirrel", {
name: "clike",
keywords: words("base break clone continue const default delete enum extends function in class" +
" foreach local resume return this throw typeof yield constructor instanceof static"),
types: words(cTypes),
blockKeywords: words("case catch class else for foreach if switch try while"),
defKeywords: words("function local class"),
typeFirstDefinitions: true,
atoms: words("true false null"),
hooks: {"#": cppHook},
modeProps: {fold: ["brace", "include"]}
});

294
devtools/client/sourceeditor/codemirror/mode/css.js поставляемый Normal file → Executable file
Просмотреть файл

@ -12,18 +12,24 @@
"use strict";
CodeMirror.defineMode("css", function(config, parserConfig) {
var provided = parserConfig;
if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
parserConfig.inline = provided.inline;
var indentUnit = config.indentUnit,
tokenHooks = parserConfig.tokenHooks,
documentTypes = parserConfig.documentTypes || {},
mediaTypes = parserConfig.mediaTypes || {},
mediaFeatures = parserConfig.mediaFeatures || {},
mediaValueKeywords = parserConfig.mediaValueKeywords || {},
propertyKeywords = parserConfig.propertyKeywords || {},
nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
fontProperties = parserConfig.fontProperties || {},
counterDescriptors = parserConfig.counterDescriptors || {},
colorKeywords = parserConfig.colorKeywords || {},
valueKeywords = parserConfig.valueKeywords || {},
fontProperties = parserConfig.fontProperties || {},
allowNested = parserConfig.allowNested;
allowNested = parserConfig.allowNested,
supportsAtComponent = parserConfig.supportsAtComponent === true;
var type, override;
function ret(style, tp) { type = tp; return style; }
@ -57,6 +63,11 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
if (/[\d.]/.test(stream.peek())) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
} else if (stream.match(/^-[\w\\\-]+/)) {
stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false))
return ret("variable-2", "variable-definition");
return ret("variable-2", "variable");
} else if (stream.match(/^\w+-/)) {
return ret("meta", "meta");
}
@ -66,7 +77,9 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return ret("qualifier", "qualifier");
} else if (/[:;{}\[\]\(\)]/.test(ch)) {
return ret(null, ch);
} else if (ch == "u" && stream.match("rl(")) {
} else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) ||
(ch == "d" && stream.match("omain(")) ||
(ch == "r" && stream.match("egexp("))) {
stream.backUp(1);
state.tokenize = tokenParenthesized;
return ret("property", "word");
@ -110,13 +123,14 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
this.prev = prev;
}
function pushContext(state, stream, type) {
state.context = new Context(type, stream.indentation() + indentUnit, state.context);
function pushContext(state, stream, type, indent) {
state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
return type;
}
function popContext(state) {
state.context = state.context.prev;
if (state.context.prev)
state.context = state.context.prev;
return state.context.type;
}
@ -148,10 +162,15 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return pushContext(state, stream, "block");
} else if (type == "}" && state.context.prev) {
return popContext(state);
} else if (type == "@media") {
return pushContext(state, stream, "media");
} else if (type == "@font-face") {
return "font_face_before";
} else if (supportsAtComponent && /@component/.test(type)) {
return pushContext(state, stream, "atComponentBlock");
} else if (/^@(-moz-)?document$/.test(type)) {
return pushContext(state, stream, "documentTypes");
} else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) {
return pushContext(state, stream, "atBlock");
} else if (/^@(font-face|counter-style)/.test(type)) {
state.stateArg = type;
return "restricted_atBlock_before";
} else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
return "keyframes";
} else if (type && type.charAt(0) == "@") {
@ -182,7 +201,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
override = "string-2";
return "maybeprop";
} else if (allowNested) {
override = stream.match(/^\s*:/, false) ? "property" : "tag";
override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
return "block";
} else {
override += " error";
@ -229,6 +248,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
if (type == "{" || type == "}") return popAndPass(type, stream, state);
if (type == ")") return popContext(state);
if (type == "(") return pushContext(state, stream, "parens");
if (type == "interpolation") return pushContext(state, stream, "interpolation");
if (type == "word") wordAsValue(stream);
return "parens";
};
@ -241,47 +261,84 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return pass(type, stream, state);
};
states.media = function(type, stream, state) {
if (type == "(") return pushContext(state, stream, "media_parens");
if (type == "}") return popAndPass(type, stream, state);
states.documentTypes = function(type, stream, state) {
if (type == "word" && documentTypes.hasOwnProperty(stream.current())) {
override = "tag";
return state.context.type;
} else {
return states.atBlock(type, stream, state);
}
};
states.atBlock = function(type, stream, state) {
if (type == "(") return pushContext(state, stream, "atBlock_parens");
if (type == "}" || type == ";") return popAndPass(type, stream, state);
if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
if (type == "word") {
var word = stream.current().toLowerCase();
if (word == "only" || word == "not" || word == "and")
if (word == "only" || word == "not" || word == "and" || word == "or")
override = "keyword";
else if (mediaTypes.hasOwnProperty(word))
override = "attribute";
else if (mediaFeatures.hasOwnProperty(word))
override = "property";
else if (mediaValueKeywords.hasOwnProperty(word))
override = "keyword";
else if (propertyKeywords.hasOwnProperty(word))
override = "property";
else if (nonStandardPropertyKeywords.hasOwnProperty(word))
override = "string-2";
else if (valueKeywords.hasOwnProperty(word))
override = "atom";
else if (colorKeywords.hasOwnProperty(word))
override = "keyword";
else
override = "error";
}
return state.context.type;
};
states.media_parens = function(type, stream, state) {
if (type == ")") return popContext(state);
if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
return states.media(type, stream, state);
states.atComponentBlock = function(type, stream, state) {
if (type == "}")
return popAndPass(type, stream, state);
if (type == "{")
return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false);
if (type == "word")
override = "error";
return state.context.type;
};
states.font_face_before = function(type, stream, state) {
states.atBlock_parens = function(type, stream, state) {
if (type == ")") return popContext(state);
if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
return states.atBlock(type, stream, state);
};
states.restricted_atBlock_before = function(type, stream, state) {
if (type == "{")
return pushContext(state, stream, "font_face");
return pushContext(state, stream, "restricted_atBlock");
if (type == "word" && state.stateArg == "@counter-style") {
override = "variable";
return "restricted_atBlock_before";
}
return pass(type, stream, state);
};
states.font_face = function(type, stream, state) {
if (type == "}") return popContext(state);
states.restricted_atBlock = function(type, stream, state) {
if (type == "}") {
state.stateArg = null;
return popContext(state);
}
if (type == "word") {
if (!fontProperties.hasOwnProperty(stream.current().toLowerCase()))
if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
(state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
override = "error";
else
override = "property";
return "maybeprop";
}
return "font_face";
return "restricted_atBlock";
};
states.keyframes = function(type, stream, state) {
@ -301,15 +358,17 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
states.interpolation = function(type, stream, state) {
if (type == "}") return popContext(state);
if (type == "{" || type == ";") return popAndPass(type, stream, state);
if (type != "variable") override = "error";
if (type == "word") override = "variable";
else if (type != "variable" && type != "(" && type != ")") override = "error";
return "interpolation";
};
return {
startState: function(base) {
return {tokenize: null,
state: "top",
context: new Context("top", base || 0, null)};
state: parserConfig.inline ? "block" : "top",
stateArg: null,
context: new Context(parserConfig.inline ? "block" : "top", base || 0, null)};
},
token: function(stream, state) {
@ -328,12 +387,18 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
var cx = state.context, ch = textAfter && textAfter.charAt(0);
var indent = cx.indent;
if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
if (cx.prev &&
(ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "font_face") ||
ch == ")" && (cx.type == "parens" || cx.type == "media_parens") ||
ch == "{" && (cx.type == "at" || cx.type == "media"))) {
indent = cx.indent - indentUnit;
cx = cx.prev;
if (cx.prev) {
if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
// Resume indentation from parent context.
cx = cx.prev;
indent = cx.indent;
} else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
// Dedent relative to current context.
indent = Math.max(0, cx.indent - indentUnit);
cx = cx.prev;
}
}
return indent;
},
@ -353,6 +418,10 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return keys;
}
var documentTypes_ = [
"domain", "regexp", "url", "url-prefix"
], documentTypes = keySet(documentTypes_);
var mediaTypes_ = [
"all", "aural", "braille", "handheld", "print", "projection", "screen",
"tty", "tv", "embossed"
@ -366,9 +435,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
"max-color", "color-index", "min-color-index", "max-color-index",
"monochrome", "min-monochrome", "max-monochrome", "resolution",
"min-resolution", "max-resolution", "scan", "grid"
"min-resolution", "max-resolution", "scan", "grid", "orientation",
"device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
"pointer", "any-pointer", "hover", "any-hover"
], mediaFeatures = keySet(mediaFeatures_);
var mediaValueKeywords_ = [
"landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
"interlace", "progressive"
], mediaValueKeywords = keySet(mediaValueKeywords_);
var propertyKeywords_ = [
"align-content", "align-items", "align-self", "alignment-adjust",
"alignment-baseline", "anchor-point", "animation", "animation-delay",
@ -461,13 +537,23 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"glyph-orientation-vertical", "text-anchor", "writing-mode"
], propertyKeywords = keySet(propertyKeywords_);
var nonStandardPropertyKeywords = [
var nonStandardPropertyKeywords_ = [
"scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
"scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
"searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
"searchfield-results-decoration", "zoom"
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords);
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
var fontProperties_ = [
"font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
"font-stretch", "font-weight", "font-style"
], fontProperties = keySet(fontProperties_);
var counterDescriptors_ = [
"additive-symbols", "fallback", "negative", "pad", "prefix", "range",
"speak-as", "suffix", "symbols", "system"
], counterDescriptors = keySet(counterDescriptors_);
var colorKeywords_ = [
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
@ -491,54 +577,57 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
"orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
"papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
"purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon",
"sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
"purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
"salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
"slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
"whitesmoke", "yellow", "yellowgreen"
], colorKeywords = keySet(colorKeywords_);
var valueKeywords_ = [
"above", "absolute", "activeborder", "activecaption", "afar",
"after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
"above", "absolute", "activeborder", "additive", "activecaption", "afar",
"after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
"arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page",
"arabic-indic", "armenian", "asterisks", "attr", "auto", "avoid", "avoid-column", "avoid-page",
"avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
"bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
"both", "bottom", "break", "break-all", "break-word", "button", "button-bevel",
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
"both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
"cell", "center", "checkbox", "circle", "cjk-earthly-branch",
"cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
"col-resize", "collapse", "column", "compact", "condensed", "contain", "content",
"content-box", "context-menu", "continuous", "copy", "cover", "crop",
"cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
"col-resize", "collapse", "column", "column-reverse", "compact", "condensed", "contain", "content",
"content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
"cross", "crosshair", "currentcolor", "cursive", "cyclic", "dashed", "decimal",
"decimal-leading-zero", "default", "default-button", "destination-atop",
"destination-in", "destination-out", "destination-over", "devanagari",
"disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
"double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
"disc", "discard", "disclosure-closed", "disclosure-open", "document",
"dot-dash", "dot-dot-dash",
"dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
"element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
"ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
"ethiopic-halehame-gez", "ethiopic-halehame-om-et",
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et",
"ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed",
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes",
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
"ethiopic-numeric", "ew-resize", "expanded", "extends", "extra-condensed",
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
"forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
"inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
"italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer",
"inline-block", "inline-flex", "inline-table", "inset", "inside", "intrinsic", "invert",
"italic", "japanese-formal", "japanese-informal", "justify", "kannada",
"katakana", "katakana-iroha", "keep-all", "khmer",
"korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
"landscape", "lao", "large", "larger", "left", "level", "lighter",
"line-through", "linear", "lines", "list-item", "listbox", "listitem",
"line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
"lower-roman", "lowercase", "ltr", "malayalam", "match",
"lower-roman", "lowercase", "ltr", "malayalam", "match", "matrix", "matrix3d",
"media-controls-background", "media-current-time-display",
"media-fullscreen-button", "media-mute-button", "media-play-button",
"media-return-to-realtime-button", "media-rewind-button",
@ -550,46 +639,50 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
"ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
"ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
"painted", "page", "paused", "persian", "plus-darker", "plus-lighter", "pointer",
"polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
"radio", "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region",
"relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
"ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
"s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
"painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
"pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
"progress", "push-button", "radial-gradient", "radio", "read-only",
"read-write", "read-write-plaintext-only", "rectangle", "region",
"relative", "repeat", "repeating-linear-gradient",
"repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
"rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
"rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
"s-resize", "sans-serif", "scale", "scale3d", "scaleX", "scaleY", "scaleZ",
"scroll", "scrollbar", "se-resize", "searchfield",
"searchfield-cancel-button", "searchfield-decoration",
"searchfield-results-button", "searchfield-results-decoration",
"semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
"single", "skip-white-space", "slide", "slider-horizontal",
"simp-chinese-formal", "simp-chinese-informal", "single",
"skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "solid", "somali",
"source-atop", "source-in", "source-out", "source-over", "space", "square",
"square-button", "start", "static", "status-bar", "stretch", "stroke",
"sub", "subpixel-antialiased", "super", "sw-resize", "table",
"source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "spell-out", "square",
"square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
"subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table",
"table-caption", "table-cell", "table-column", "table-column-group",
"table-footer-group", "table-header-group", "table-row", "table-row-group",
"tamil",
"telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
"thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
"threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
"trad-chinese-formal", "trad-chinese-informal",
"translate", "translate3d", "translateX", "translateY", "translateZ",
"transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
"vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
"var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
"window", "windowframe", "windowtext", "x-large", "x-small", "xor",
"window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
"xx-large", "xx-small"
], valueKeywords = keySet(valueKeywords_);
var fontProperties_ = [
"font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
"font-stretch", "font-weight", "font-style"
], fontProperties = keySet(fontProperties_);
var allWords = mediaTypes_.concat(mediaFeatures_).concat(propertyKeywords_)
.concat(nonStandardPropertyKeywords).concat(colorKeywords_).concat(valueKeywords_);
var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_)
.concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_)
.concat(valueKeywords_);
CodeMirror.registerHelper("hintWords", "css", allWords);
function tokenCComment(stream, state) {
@ -604,30 +697,18 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return ["comment", "comment"];
}
function tokenSGMLComment(stream, state) {
if (stream.skipTo("-->")) {
stream.match("-->");
state.tokenize = null;
} else {
stream.skipToEnd();
}
return ["comment", "comment"];
}
CodeMirror.defineMIME("text/css", {
documentTypes: documentTypes,
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
mediaValueKeywords: mediaValueKeywords,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
fontProperties: fontProperties,
counterDescriptors: counterDescriptors,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
fontProperties: fontProperties,
tokenHooks: {
"<": function(stream, state) {
if (!stream.match("!--")) return false;
state.tokenize = tokenSGMLComment;
return tokenSGMLComment(stream, state);
},
"/": function(stream, state) {
if (!stream.eat("*")) return false;
state.tokenize = tokenCComment;
@ -640,6 +721,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
CodeMirror.defineMIME("text/x-scss", {
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
mediaValueKeywords: mediaValueKeywords,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
colorKeywords: colorKeywords,
@ -659,7 +741,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
}
},
":": function(stream) {
if (stream.match(/\s*{/))
if (stream.match(/\s*\{/))
return [null, "{"];
return false;
},
@ -681,6 +763,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
CodeMirror.defineMIME("text/x-less", {
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
mediaValueKeywords: mediaValueKeywords,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
colorKeywords: colorKeywords,
@ -700,6 +783,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
}
},
"@": function(stream) {
if (stream.eat("{")) return [null, "interpolation"];
if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false))
@ -714,4 +798,26 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
helperType: "less"
});
CodeMirror.defineMIME("text/x-gss", {
documentTypes: documentTypes,
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
fontProperties: fontProperties,
counterDescriptors: counterDescriptors,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
supportsAtComponent: true,
tokenHooks: {
"/": function(stream, state) {
if (!stream.eat("*")) return false;
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
}
},
name: "css",
helperType: "gss"
});
});

216
devtools/client/sourceeditor/codemirror/mode/htmlmixed.js поставляемый Normal file → Executable file
Просмотреть файл

@ -9,112 +9,142 @@
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
"use strict";
CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
var htmlMode = CodeMirror.getMode(config, {name: "xml",
htmlMode: true,
multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag});
var cssMode = CodeMirror.getMode(config, "css");
var defaultTags = {
script: [
["lang", /(javascript|babel)/i, "javascript"],
["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i, "javascript"],
["type", /./, "text/plain"],
[null, null, "javascript"]
],
style: [
["lang", /^css$/i, "css"],
["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"],
["type", /./, "text/plain"],
[null, null, "css"]
]
};
var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes;
scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,
mode: CodeMirror.getMode(config, "javascript")});
if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) {
var conf = scriptTypesConf[i];
scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)});
}
scriptTypes.push({matches: /./,
mode: CodeMirror.getMode(config, "text/plain")});
function html(stream, state) {
var tagName = state.htmlState.tagName;
var style = htmlMode.token(stream, state.htmlState);
if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") {
// Script block: mode to change to depends on type attribute
var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
scriptType = scriptType ? scriptType[1] : "";
if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1);
for (var i = 0; i < scriptTypes.length; ++i) {
var tp = scriptTypes[i];
if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) {
if (tp.mode) {
state.token = script;
state.localMode = tp.mode;
state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, ""));
}
break;
}
}
} else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") {
state.token = css;
state.localMode = cssMode;
state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
}
return style;
}
function maybeBackup(stream, pat, style) {
var cur = stream.current();
var close = cur.search(pat), m;
if (close > -1) stream.backUp(cur.length - close);
else if (m = cur.match(/<\/?$/)) {
var cur = stream.current(), close = cur.search(pat);
if (close > -1) {
stream.backUp(cur.length - close);
} else if (cur.match(/<\/?$/)) {
stream.backUp(cur.length);
if (!stream.match(pat, false)) stream.match(cur);
}
return style;
}
function script(stream, state) {
if (stream.match(/^<\/\s*script\s*>/i, false)) {
state.token = html;
state.localState = state.localMode = null;
return html(stream, state);
}
return maybeBackup(stream, /<\/\s*script\s*>/,
state.localMode.token(stream, state.localState));
}
function css(stream, state) {
if (stream.match(/^<\/\s*style\s*>/i, false)) {
state.token = html;
state.localState = state.localMode = null;
return html(stream, state);
}
return maybeBackup(stream, /<\/\s*style\s*>/,
cssMode.token(stream, state.localState));
var attrRegexpCache = {};
function getAttrRegexp(attr) {
var regexp = attrRegexpCache[attr];
if (regexp) return regexp;
return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*");
}
return {
startState: function() {
var state = htmlMode.startState();
return {token: html, localMode: null, localState: null, htmlState: state};
},
function getAttrValue(stream, attr) {
var pos = stream.pos, match;
while (pos >= 0 && stream.string.charAt(pos) !== "<") pos--;
if (pos < 0) return pos;
if (match = stream.string.slice(pos, stream.pos).match(getAttrRegexp(attr)))
return match[2];
return "";
}
copyState: function(state) {
if (state.localState)
var local = CodeMirror.copyState(state.localMode, state.localState);
return {token: state.token, localMode: state.localMode, localState: local,
htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
},
function getTagRegexp(tagName, anchored) {
return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i");
}
token: function(stream, state) {
return state.token(stream, state);
},
indent: function(state, textAfter) {
if (!state.localMode || /^\s*<\//.test(textAfter))
return htmlMode.indent(state.htmlState, textAfter);
else if (state.localMode.indent)
return state.localMode.indent(state.localState, textAfter);
else
return CodeMirror.Pass;
},
innerMode: function(state) {
return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
function addTags(from, to) {
for (var tag in from) {
var dest = to[tag] || (to[tag] = []);
var source = from[tag];
for (var i = source.length - 1; i >= 0; i--)
dest.unshift(source[i])
}
};
}, "xml", "javascript", "css");
}
CodeMirror.defineMIME("text/html", "htmlmixed");
function findMatchingMode(tagInfo, stream) {
for (var i = 0; i < tagInfo.length; i++) {
var spec = tagInfo[i];
if (!spec[0] || spec[1].test(getAttrValue(stream, spec[0]))) return spec[2];
}
}
CodeMirror.defineMode("htmlmixed", function (config, parserConfig) {
var htmlMode = CodeMirror.getMode(config, {
name: "xml",
htmlMode: true,
multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag
});
var tags = {};
var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes;
addTags(defaultTags, tags);
if (configTags) addTags(configTags, tags);
if (configScript) for (var i = configScript.length - 1; i >= 0; i--)
tags.script.unshift(["type", configScript[i].matches, configScript[i].mode])
function html(stream, state) {
var tagName = state.htmlState.tagName;
var tagInfo = tagName && tags[tagName.toLowerCase()];
var style = htmlMode.token(stream, state.htmlState), modeSpec;
if (tagInfo && /\btag\b/.test(style) && stream.current() === ">" &&
(modeSpec = findMatchingMode(tagInfo, stream))) {
var mode = CodeMirror.getMode(config, modeSpec);
var endTagA = getTagRegexp(tagName, true), endTag = getTagRegexp(tagName, false);
state.token = function (stream, state) {
if (stream.match(endTagA, false)) {
state.token = html;
state.localState = state.localMode = null;
return null;
}
return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState));
};
state.localMode = mode;
state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, ""));
}
return style;
};
return {
startState: function () {
var state = htmlMode.startState();
return {token: html, localMode: null, localState: null, htmlState: state};
},
copyState: function (state) {
var local;
if (state.localState) {
local = CodeMirror.copyState(state.localMode, state.localState);
}
return {token: state.token, localMode: state.localMode, localState: local,
htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
},
token: function (stream, state) {
return state.token(stream, state);
},
indent: function (state, textAfter) {
if (!state.localMode || /^\s*<\//.test(textAfter))
return htmlMode.indent(state.htmlState, textAfter);
else if (state.localMode.indent)
return state.localMode.indent(state.localState, textAfter);
else
return CodeMirror.Pass;
},
innerMode: function (state) {
return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
}
};
}, "xml", "javascript", "css");
CodeMirror.defineMIME("text/html", "htmlmixed");
});

113
devtools/client/sourceeditor/codemirror/mode/javascript.js поставляемый Normal file → Executable file
Просмотреть файл

@ -19,6 +19,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var jsonldMode = parserConfig.jsonld;
var jsonMode = parserConfig.json || jsonldMode;
var isTS = parserConfig.typescript;
var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
// Tokenizer
@ -31,12 +32,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
"return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
"var": kw("var"), "const": kw("var"), "let": kw("var"),
"function": kw("function"), "catch": kw("catch"),
"async": kw("async"), "function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator,
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
"this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C
"this": kw("this"), "class": kw("class"), "super": kw("atom"),
"await": C, "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
};
// Extend the 'normal' keywords with the TypeScript language extensions
@ -104,6 +105,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} else if (ch == "0" && stream.eat(/x/i)) {
stream.eatWhile(/[\da-f]/i);
return ret("number", "number");
} else if (ch == "0" && stream.eat(/o/i)) {
stream.eatWhile(/[0-7]/i);
return ret("number", "number");
} else if (ch == "0" && stream.eat(/b/i)) {
stream.eatWhile(/[01]/i);
return ret("number", "number");
} else if (/\d/.test(ch)) {
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
return ret("number", "number");
@ -117,7 +124,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} else if (state.lastType == "operator" || state.lastType == "keyword c" ||
state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
readRegexp(stream);
stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
return ret("regexp", "string-2");
} else {
stream.eatWhile(isOperatorChar);
@ -132,8 +139,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} else if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return ret("operator", "operator", stream.current());
} else {
stream.eatWhile(/[\w\$_]/);
} else if (wordRE.test(ch)) {
stream.eatWhile(wordRE);
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
ret("variable", "variable", word);
@ -202,8 +209,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (--depth == 0) break;
} else if (bracket >= 3 && bracket < 6) {
++depth;
} else if (/[$\w]/.test(ch)) {
} else if (wordRE.test(ch)) {
sawSomething = true;
} else if (/["'\/]/.test(ch)) {
return;
} else if (sawSomething && !depth) {
++pos;
break;
@ -238,7 +247,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var cc = state.cc;
// Communicate our context to the combinators.
// (Less wasteful than consing up a hundred closures on every call.)
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
if (!state.lexical.hasOwnProperty("align"))
state.lexical.align = true;
@ -298,6 +307,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var result = function() {
var state = cx.state, indent = state.indented;
if (state.lexical.type == "stat") indent = state.lexical.indented;
else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
indent = outer.indented;
state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
};
result.lex = true;
@ -342,10 +353,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "default") return cont(expect(":"));
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
statement, poplex, popcontext);
if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
if (type == "class") return cont(pushlex("form"), className, objlit, poplex);
if (type == "export") return cont(pushlex("form"), afterExport, poplex);
if (type == "import") return cont(pushlex("form"), afterImport, poplex);
if (type == "class") return cont(pushlex("form"), className, poplex);
if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
return pass(pushlex("stat"), expression, expect(";"), poplex);
}
function expression(type) {
@ -363,6 +373,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "async") return cont(expression);
if (type == "function") return cont(functiondef, maybeop);
if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
@ -388,7 +399,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function maybeoperatorNoComma(type, value, noComma) {
var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
var expr = noComma == false ? expression : expressionNoComma;
if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
if (type == "operator") {
if (/\+\+|--/.test(value)) return cont(me);
if (value == "?") return cont(expression, expect(":"), expr);
@ -414,13 +425,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function arrowBody(type) {
findFatArrow(cx.stream, cx.state);
if (type == "{") return pass(statement);
return pass(expression);
return pass(type == "{" ? statement : expression);
}
function arrowBodyNoComma(type) {
findFatArrow(cx.stream, cx.state);
if (type == "{") return pass(statement);
return pass(expressionNoComma);
return pass(type == "{" ? statement : expressionNoComma);
}
function maybelabel(type) {
if (type == ":") return cont(poplex, statement);
@ -430,15 +439,20 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "variable") {cx.marked = "property"; return cont();}
}
function objprop(type, value) {
if (type == "variable") {
if (type == "async") {
return cont(objprop);
} else if (type == "variable" || cx.style == "keyword") {
cx.marked = "property";
if (value == "get" || value == "set") return cont(getterSetter);
return cont(afterprop);
} else if (type == "number" || type == "string") {
cx.marked = jsonldMode ? "property" : (type + " property");
cx.marked = jsonldMode ? "property" : (cx.style + " property");
return cont(afterprop);
} else if (type == "jsonld-keyword") {
return cont(afterprop);
} else if (type == "[") {
return cont(expression, expect("]"), afterprop);
}
if (atomicTypes.hasOwnProperty(type)) return cont(afterprop);
}
function getterSetter(type) {
if (type != "variable") return pass(afterprop);
@ -476,8 +490,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function maybetype(type) {
if (isTS && type == ":") return cont(typedef);
}
function maybedefault(_, value) {
if (value == "=") return cont(expressionNoComma);
}
function typedef(type) {
if (type == "variable"){cx.marked = "variable-3"; return cont();}
if (type == "variable") {cx.marked = "variable-3"; return cont();}
}
function vardef() {
return pass(pattern, maybetype, maybeAssign, vardefCont);
@ -532,20 +549,36 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function funarg(type) {
if (type == "spread") return cont(funarg);
return pass(pattern, maybetype);
return pass(pattern, maybetype, maybedefault);
}
function className(type, value) {
if (type == "variable") {register(value); return cont(classNameAfter);}
}
function classNameAfter(_type, value) {
if (value == "extends") return cont(expression);
function classNameAfter(type, value) {
if (value == "extends") return cont(expression, classNameAfter);
if (type == "{") return cont(pushlex("}"), classBody, poplex);
}
function objlit(type) {
if (type == "{") return contCommasep(objprop, "}");
function classBody(type, value) {
if (type == "variable" || cx.style == "keyword") {
if (value == "static") {
cx.marked = "keyword";
return cont(classBody);
}
cx.marked = "property";
if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
return cont(functiondef, classBody);
}
if (value == "*") {
cx.marked = "keyword";
return cont(classBody);
}
if (type == ";") return cont(classBody);
if (type == "}") return cont();
}
function afterModule(type, value) {
if (type == "string") return cont(statement);
if (type == "variable") { register(value); return cont(maybeFrom); }
function classGetterSetter(type) {
if (type != "variable") return pass();
cx.marked = "property";
return cont();
}
function afterExport(_type, value) {
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
@ -559,7 +592,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function importSpec(type, value) {
if (type == "{") return contCommasep(importSpec, "}");
if (type == "variable") register(value);
return cont();
if (value == "*") cx.marked = "keyword";
return cont(maybeAs);
}
function maybeAs(_type, value) {
if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
}
function maybeFrom(_type, value) {
if (value == "from") { cx.marked = "keyword"; return cont(expression); }
@ -570,7 +607,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function maybeArrayComprehension(type) {
if (type == "for") return pass(comprehension, expect("]"));
if (type == ",") return cont(commasep(expressionNoComma, "]"));
if (type == ",") return cont(commasep(maybeexpressionNoComma, "]"));
return pass(commasep(expressionNoComma, "]"));
}
function comprehension(type) {
@ -578,6 +615,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "if") return cont(expression, comprehension);
}
function isContinuedStatement(state, textAfter) {
return state.lastType == "operator" || state.lastType == "," ||
isOperatorChar.test(textAfter.charAt(0)) ||
/[,.]/.test(textAfter.charAt(0));
}
// Interface
return {
@ -629,18 +672,19 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
else if (type == "form" && firstChar == "{") return lexical.indented;
else if (type == "form") return lexical.indented + indentUnit;
else if (type == "stat")
return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
else return lexical.indented + (closing ? 0 : indentUnit);
},
electricChars: ":{}",
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
blockCommentStart: jsonMode ? null : "/*",
blockCommentEnd: jsonMode ? null : "*/",
lineComment: jsonMode ? null : "//",
fold: "brace",
closeBrackets: "()[]{}''\"\"``",
helperType: jsonMode ? "json" : "javascript",
jsonldMode: jsonldMode,
@ -648,11 +692,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
};
});
CodeMirror.registerHelper("wordChars", "javascript", /[\\w$]/);
CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
CodeMirror.defineMIME("text/javascript", "javascript");
CodeMirror.defineMIME("text/ecmascript", "javascript");
CodeMirror.defineMIME("application/javascript", "javascript");
CodeMirror.defineMIME("application/x-javascript", "javascript");
CodeMirror.defineMIME("application/ecmascript", "javascript");
CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});

3
devtools/client/sourceeditor/codemirror/mode/xml.js поставляемый Normal file → Executable file
Просмотреть файл

@ -21,7 +21,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
'track': true, 'wbr': true},
'track': true, 'wbr': true, 'menuitem': true},
implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
'th': true, 'tr': true},
@ -109,6 +109,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
return null;
}
}
inText.isInText = true;
function inTag(stream, state) {
var ch = stream.next();

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

@ -606,6 +606,7 @@ Editor.prototype = {
let cm = editors.get(this);
this.alignLine(line, align);
cm.setCursor({line: line, ch: ch});
this.emit("cursorActivity");
},
/**
@ -1024,6 +1025,7 @@ Editor.prototype = {
this.setupAutoCompletion();
} else {
cm.setOption(o, v);
this.config[o] = v;
}
if (o === "enableCodeFolding") {

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

@ -9,6 +9,9 @@ namespace = "comment_";
}
var simpleProg = "function foo() {\n return bar;\n}";
var inlineBlock = "foo(/* bar */ true);";
var inlineBlocks = "foo(/* bar */ true, /* baz */ false);";
var multiLineInlineBlock = ["above();", "foo(/* bar */ true);", "below();"];
test("block", "javascript", function(cm) {
cm.blockComment(Pos(0, 3), Pos(3, 0), {blockCommentLead: " *"});
@ -19,6 +22,17 @@ namespace = "comment_";
cm.uncomment(Pos(0, 3), Pos(2, 0), {blockCommentLead: " *"});
}, simpleProg, simpleProg);
test("blockToggle2", "javascript", function(cm) {
cm.setCursor({line: 0, ch: 7 /* inside the block comment */});
cm.execCommand("toggleComment");
}, inlineBlock, "foo(bar true);");
// This test should work but currently fails.
// test("blockToggle3", "javascript", function(cm) {
// cm.setCursor({line: 0, ch: 7 /* inside the first block comment */});
// cm.execCommand("toggleComment");
// }, inlineBlocks, "foo(bar true, /* baz */ false);");
test("line", "javascript", function(cm) {
cm.lineComment(Pos(1, 1), Pos(1, 1));
}, simpleProg, "function foo() {\n// return bar;\n}");
@ -36,6 +50,29 @@ namespace = "comment_";
cm.blockComment(Pos(0, 0), Pos(1));
}, "def blah()\n return hah\n", "# def blah()\n# return hah\n");
test("ignoreExternalBlockComments", "javascript", function(cm) {
cm.execCommand("toggleComment");
}, inlineBlocks, "// " + inlineBlocks);
test("ignoreExternalBlockComments2", "javascript", function(cm) {
cm.setCursor({line: 0, ch: null /* eol */});
cm.execCommand("toggleComment");
}, inlineBlocks, "// " + inlineBlocks);
test("ignoreExternalBlockCommentsMultiLineAbove", "javascript", function(cm) {
cm.setSelection({line: 0, ch: 0}, {line: 1, ch: 1});
cm.execCommand("toggleComment");
}, multiLineInlineBlock.join("\n"), ["// " + multiLineInlineBlock[0],
"// " + multiLineInlineBlock[1],
multiLineInlineBlock[2]].join("\n"));
test("ignoreExternalBlockCommentsMultiLineBelow", "javascript", function(cm) {
cm.setSelection({line: 1, ch: 13 /* after end of block comment */}, {line: 2, ch: 1});
cm.execCommand("toggleComment");
}, multiLineInlineBlock.join("\n"), [multiLineInlineBlock[0],
"// " + multiLineInlineBlock[1],
"// " + multiLineInlineBlock[2]].join("\n"));
test("commentRange", "javascript", function(cm) {
cm.blockComment(Pos(1, 2), Pos(1, 13), {fullLines: false});
}, simpleProg, "function foo() {\n /*return bar;*/\n}");

2
devtools/client/sourceeditor/test/codemirror/driver.js Normal file → Executable file
Просмотреть файл

@ -76,7 +76,7 @@ function runTests(callback) {
}
}
if (!threw) {
if (expFail) callback("fail", test.name, message || "expected failure, but succeeded");
if (expFail) callback("fail", test.name, message || "expected failure, but passed");
else callback("ok", test.name, message);
}
if (!quit) { // Run next test

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

@ -128,11 +128,20 @@
sim("clearMark", "abcde", Pos(0, 2), "Ctrl-Space", "Ctrl-F", "Ctrl-F",
"Ctrl-G", "Ctrl-W", txt("abcde"));
testCM("saveRequested", function(cm) {
sim("delRegion", "abcde", "Ctrl-Space", "Ctrl-F", "Ctrl-F", "Delete", txt("cde"));
sim("backspaceRegion", "abcde", "Ctrl-Space", "Ctrl-F", "Ctrl-F", "Backspace", txt("cde"));
testCM("save", function(cm) {
var saved = false;
CodeMirror.commands.save = function(cm) { saved = cm.getValue(); };
cm.triggerOnKeyDown(fakeEvent("Ctrl-X"));
cm.triggerOnKeyDown(fakeEvent("Ctrl-S"));
is(saved, "hi");
}, {value: "hi", keyMap: "emacs"});
testCM("gotoInvalidLineFloat", function(cm) {
cm.openDialog = function(_, cb) { cb("2.2"); };
cm.triggerOnKeyDown(fakeEvent("Alt-G"));
cm.triggerOnKeyDown(fakeEvent("G"));
}, {value: "1\n2\n3\n4", keyMap: "emacs"});
})();

63
devtools/client/sourceeditor/test/codemirror/mode/javascript/test.js поставляемый Normal file → Executable file
Просмотреть файл

@ -1,3 +1,6 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "javascript");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); }
@ -14,25 +17,26 @@
" [[[variable-2 c], [variable y] ]] [operator =] [variable-2 c];",
"})();");
MT("class_body",
"[keyword class] [variable Foo] {",
" [property constructor]() {}",
" [property sayName]() {",
" [keyword return] [string-2 `foo${][variable foo][string-2 }oo`];",
" }",
"}");
MT("class",
"[keyword class] [variable Point] [keyword extends] [variable SuperThing] {",
" [[ [string-2 /expr/] ]]: [number 24],",
" [property get] [property prop]() { [keyword return] [number 24]; }",
" [property constructor]([def x], [def y]) {",
" [keyword super]([string 'something']);",
" [keyword this].[property x] [operator =] [variable-2 x];",
" }",
"}");
MT("module",
"[keyword module] [string 'foo'] {",
" [keyword export] [keyword let] [def x] [operator =] [number 42];",
" [keyword export] [keyword *] [keyword from] [string 'somewhere'];",
"}");
MT("import",
"[keyword function] [variable foo]() {",
" [keyword import] [def $] [keyword from] [string 'jquery'];",
" [keyword module] [def crypto] [keyword from] [string 'crypto'];",
" [keyword import] { [def encrypt], [def decrypt] } [keyword from] [string 'crypto'];",
"}");
@ -50,6 +54,12 @@
" [keyword yield] [variable-2 i];",
"}");
MT("quotedStringAddition",
"[keyword let] [variable f] [operator =] [variable a] [operator +] [string 'fatarrow'] [operator +] [variable c];");
MT("quotedFatArrow",
"[keyword let] [variable f] [operator =] [variable a] [operator +] [string '=>'] [operator +] [variable c];");
MT("fatArrow",
"[variable array].[property filter]([def a] [operator =>] [variable-2 a] [operator +] [number 1]);",
"[variable a];", // No longer in scope
@ -70,6 +80,9 @@
MT("quasi",
"[variable re][string-2 `fofdlakj${][variable x] [operator +] ([variable re][string-2 `foo`]) [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]");
MT("quasi_no_function",
"[variable x] [operator =] [string-2 `fofdlakj${][variable x] [operator +] [string-2 `foo`] [operator +] [number 1][string-2 }fdsa`] [operator +] [number 2]");
MT("indent_statement",
"[keyword var] [variable x] [operator =] [number 10]",
"[variable x] [operator +=] [variable y] [operator +]",
@ -104,6 +117,28 @@
" [keyword debugger];",
"}");
MT("indent_else",
"[keyword for] (;;)",
" [keyword if] ([variable foo])",
" [keyword if] ([variable bar])",
" [number 1];",
" [keyword else]",
" [number 2];",
" [keyword else]",
" [number 3];");
MT("indent_funarg",
"[variable foo]([number 10000],",
" [keyword function]([def a]) {",
" [keyword debugger];",
"};");
MT("indent_below_if",
"[keyword for] (;;)",
" [keyword if] ([variable foo])",
" [number 1];",
"[number 2];");
MT("multilinestring",
"[keyword var] [variable x] [operator =] [string 'foo\\]",
"[string bar'];");
@ -111,6 +146,18 @@
MT("scary_regexp",
"[string-2 /foo[[/]]bar/];");
MT("indent_strange_array",
"[keyword var] [variable x] [operator =] [[",
" [number 1],,",
" [number 2],",
"]];",
"[number 10];");
MT("param_default",
"[keyword function] [variable foo]([def x] [operator =] [string-2 `foo${][number 10][string-2 }bar`]) {",
" [keyword return] [variable-2 x];",
"}");
var jsonld_mode = CodeMirror.getMode(
{indentUnit: 2},
{name: "javascript", jsonld: true}

272
devtools/client/sourceeditor/test/codemirror/test.js Normal file → Executable file
Просмотреть файл

@ -3,7 +3,7 @@ var Pos = CodeMirror.Pos;
CodeMirror.defaults.rtlMoveVisually = true;
function forEach(arr, f) {
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i], i);
}
function addDoc(cm, width, height) {
@ -359,6 +359,15 @@ testCM("undoSelectionAsBefore", function(cm) {
eq(cm.getSelection(), "abc");
});
testCM("selectionChangeConfusesHistory", function(cm) {
cm.replaceSelection("abc", null, "dontmerge");
cm.operation(function() {
cm.setCursor(Pos(0, 0));
cm.replaceSelection("abc", null, "dontmerge");
});
eq(cm.historySize().undo, 2);
});
testCM("markTextSingleLine", function(cm) {
forEach([{a: 0, b: 1, c: "", f: 2, t: 5},
{a: 0, b: 4, c: "", f: 0, t: 2},
@ -507,6 +516,17 @@ testCM("deleteSpanCollapsedInclusiveLeft", function(cm) {
cm.replaceRange("", from, to);
}, {value: "abc\nX\ndef"});
testCM("markTextCSS", function(cm) {
function present() {
var spans = cm.display.lineDiv.getElementsByTagName("span");
for (var i = 0; i < spans.length; i++)
if (spans[i].style.color == "cyan" && span[i].textContent == "cdefg") return true;
}
var m = cm.markText(Pos(0, 2), Pos(0, 6), {css: "color: cyan"});
m.clear();
is(!present());
}, {value: "abcdefgh"});
testCM("bookmark", function(cm) {
function p(v) { return v && Pos(v[0], v[1]); }
forEach([{a: [1, 0], b: [1, 1], c: "", d: [1, 4]},
@ -591,6 +611,14 @@ testCM("getAllMarks", function(cm) {
eq(cm.getAllMarks().length, 2);
});
testCM("setValueClears", function(cm) {
cm.addLineClass(0, "wrap", "foo");
var mark = cm.markText(Pos(0, 0), Pos(1, 1), {inclusiveLeft: true, inclusiveRight: true});
cm.setValue("foo");
is(!cm.lineInfo(0).wrapClass);
is(!mark.find());
}, {value: "a\nb"});
testCM("bug577", function(cm) {
cm.setValue("a\nb");
cm.clearHistory();
@ -653,7 +681,7 @@ testCM("selectAllNoScroll", function(cm) {
});
testCM("selectionPos", function(cm) {
if (phantom) return;
if (phantom || cm.getOption("inputStyle") != "textarea") return;
cm.setSize(100, 100);
addDoc(cm, 200, 100);
cm.setSelection(Pos(1, 100), Pos(98, 100));
@ -783,6 +811,7 @@ testCM("collapsedRangeCoordsChar", function(cm) {
}, {value: "123456\nabcdef\nghijkl\nmnopqr\n"});
testCM("collapsedRangeBetweenLinesSelected", function(cm) {
if (cm.getOption("inputStyle") != "textarea") return;
var widget = document.createElement("span");
widget.textContent = "\u2194";
cm.markText(Pos(0, 3), Pos(1, 0), {replacedWith: widget});
@ -975,6 +1004,14 @@ testCM("wrappingInlineWidget", function(cm) {
eq(curR.bottom, cur1.bottom);
}, {value: "1 2 3 xxx 4", lineWrapping: true});
testCM("showEmptyWidgetSpan", function(cm) {
var marker = cm.markText(Pos(0, 2), Pos(0, 2), {
clearWhenEmpty: false,
replacedWith: document.createTextNode("X")
});
eq(cm.display.view[0].text.textContent, "abXc");
}, {value: "abc"});
testCM("changedInlineWidget", function(cm) {
cm.setSize("10em");
var w = document.createElement("span");
@ -1063,6 +1100,7 @@ testCM("measureEndOfLine", function(cm) {
}, {mode: "text/html", value: "<!-- foo barrr -->", lineWrapping: true}, ie_lt8 || opera_lt10);
testCM("scrollVerticallyAndHorizontally", function(cm) {
if (cm.getOption("inputStyle") != "textarea") return;
cm.setSize(100, 100);
addDoc(cm, 40, 40);
cm.setCursor(39);
@ -1291,10 +1329,11 @@ testCM("verticalMovementCommandsWrapping", function(cm) {
lineWrapping: true});
testCM("rtlMovement", function(cm) {
if (cm.getOption("inputStyle") != "textarea") return;
forEach(["خحج", "خحabcخحج", "abخحخحجcd", "abخde", "abخح2342خ1حج", "خ1ح2خح3حxج",
"خحcd", "1خحcd", "abcdeح1ج", "خمرحبها مها!", "foobarر", "خ ة ق",
"<img src=\"/בדיקה3.jpg\">"], function(line) {
var inv = line.charAt(0) == "خ";
"<img src=\"/בדיקה3.jpg\">", "يتم السحب في 05 فبراير 2014"], function(line) {
var inv = line.charCodeAt(0) > 128;
cm.setValue(line + "\n"); cm.execCommand(inv ? "goLineEnd" : "goLineStart");
var cursors = byClassName(cm.getWrapperElement(), "CodeMirror-cursors")[0];
var cursor = cursors.firstChild;
@ -1360,7 +1399,7 @@ testCM("lineChangeEvents", function(cm) {
});
testCM("scrollEntirelyToRight", function(cm) {
if (phantom) return;
if (phantom || cm.getOption("inputStyle") != "textarea") return;
addDoc(cm, 500, 2);
cm.setCursor(Pos(0, 500));
var wrap = cm.getWrapperElement(), cur = byClassName(wrap, "CodeMirror-cursor")[0];
@ -1407,27 +1446,79 @@ testCM("lineWidgetCautiousRedraw", function(cm) {
is(!redrawn);
}, {value: "123\n456"});
var knownScrollbarWidth;
function scrollbarWidth(measure) {
if (knownScrollbarWidth != null) return knownScrollbarWidth;
var div = document.createElement('div');
div.style.cssText = "width: 50px; height: 50px; overflow-x: scroll";
document.body.appendChild(div);
knownScrollbarWidth = div.offsetHeight - div.clientHeight;
document.body.removeChild(div);
return knownScrollbarWidth || 0;
}
testCM("lineWidgetChanged", function(cm) {
addDoc(cm, 2, 300);
cm.setSize(null, cm.defaultTextHeight() * 50);
var halfScrollbarWidth = scrollbarWidth(cm.display.measure)/2;
cm.setOption('lineNumbers', true);
cm.setSize(600, cm.defaultTextHeight() * 50);
cm.scrollTo(null, cm.heightAtLine(125, "local"));
var expectedWidgetHeight = 60;
var expectedLinesInWidget = 3;
function w() {
var node = document.createElement("div");
node.style.cssText = "background: yellow; height: 50px;";
// we use these children with just under half width of the line to check measurements are made with correct width
// when placed in the measure div.
// If the widget is measured at a width much narrower than it is displayed at, the underHalf children will span two lines and break the test.
// If the widget is measured at a width much wider than it is displayed at, the overHalf children will combine and break the test.
// Note that this test only checks widgets where coverGutter is true, because these require extra styling to get the width right.
// It may also be worthwhile to check this for non-coverGutter widgets.
// Visually:
// Good:
// | ------------- display width ------------- |
// | ------- widget-width when measured ------ |
// | | -- under-half -- | | -- under-half -- | |
// | | --- over-half --- | |
// | | --- over-half --- | |
// Height: measured as 3 lines, same as it will be when actually displayed
// Bad (too narrow):
// | ------------- display width ------------- |
// | ------ widget-width when measured ----- | < -- uh oh
// | | -- under-half -- | |
// | | -- under-half -- | | < -- when measured, shoved to next line
// | | --- over-half --- | |
// | | --- over-half --- | |
// Height: measured as 4 lines, more than expected . Will be displayed as 3 lines!
// Bad (too wide):
// | ------------- display width ------------- |
// | -------- widget-width when measured ------- | < -- uh oh
// | | -- under-half -- | | -- under-half -- | |
// | | --- over-half --- | | --- over-half --- | | < -- when measured, combined on one line
// Height: measured as 2 lines, less than expected. Will be displayed as 3 lines!
var barelyUnderHalfWidthHtml = '<div style="display: inline-block; height: 1px; width: '+(285 - halfScrollbarWidth)+'px;"></div>';
var barelyOverHalfWidthHtml = '<div style="display: inline-block; height: 1px; width: '+(305 - halfScrollbarWidth)+'px;"></div>';
node.innerHTML = new Array(3).join(barelyUnderHalfWidthHtml) + new Array(3).join(barelyOverHalfWidthHtml);
node.style.cssText = "background: yellow;font-size:0;line-height: " + (expectedWidgetHeight/expectedLinesInWidget) + "px;";
return node;
}
var info0 = cm.getScrollInfo();
var w0 = cm.addLineWidget(0, w());
var w150 = cm.addLineWidget(150, w());
var w300 = cm.addLineWidget(300, w());
var w0 = cm.addLineWidget(0, w(), { coverGutter: true });
var w150 = cm.addLineWidget(150, w(), { coverGutter: true });
var w300 = cm.addLineWidget(300, w(), { coverGutter: true });
var info1 = cm.getScrollInfo();
eq(info0.height + 150, info1.height);
eq(info0.top + 50, info1.top);
w0.node.style.height = w150.node.style.height = w300.node.style.height = "10px";
eq(info0.height + (3 * expectedWidgetHeight), info1.height);
eq(info0.top + expectedWidgetHeight, info1.top);
expectedWidgetHeight = 12;
w0.node.style.lineHeight = w150.node.style.lineHeight = w300.node.style.lineHeight = (expectedWidgetHeight/expectedLinesInWidget) + "px";
w0.changed(); w150.changed(); w300.changed();
var info2 = cm.getScrollInfo();
eq(info0.height + 30, info2.height);
eq(info0.top + 10, info2.top);
eq(info0.height + (3 * expectedWidgetHeight), info2.height);
eq(info0.top + expectedWidgetHeight, info2.top);
});
testCM("getLineNumber", function(cm) {
@ -1472,33 +1563,48 @@ testCM("jumpTheGap", function(cm) {
}, {lineWrapping: true, value: "abc\ndef\nghi\njkl\n"});
testCM("addLineClass", function(cm) {
function cls(line, text, bg, wrap) {
function cls(line, text, bg, wrap, gutter) {
var i = cm.lineInfo(line);
eq(i.textClass, text);
eq(i.bgClass, bg);
eq(i.wrapClass, wrap);
if (typeof i.handle.gutterClass !== 'undefined') {
eq(i.handle.gutterClass, gutter);
}
}
cm.addLineClass(0, "text", "foo");
cm.addLineClass(0, "text", "bar");
cm.addLineClass(1, "background", "baz");
cm.addLineClass(1, "wrap", "foo");
cls(0, "foo bar", null, null);
cls(1, null, "baz", "foo");
cm.addLineClass(1, "gutter", "gutter-class");
cls(0, "foo bar", null, null, null);
cls(1, null, "baz", "foo", "gutter-class");
var lines = cm.display.lineDiv;
eq(byClassName(lines, "foo").length, 2);
eq(byClassName(lines, "bar").length, 1);
eq(byClassName(lines, "baz").length, 1);
eq(byClassName(lines, "gutter-class").length, 2); // Gutter classes are reflected in 2 nodes
cm.removeLineClass(0, "text", "foo");
cls(0, "bar", null, null);
cls(0, "bar", null, null, null);
cm.removeLineClass(0, "text", "foo");
cls(0, "bar", null, null);
cls(0, "bar", null, null, null);
cm.removeLineClass(0, "text", "bar");
cls(0, null, null, null);
cm.addLineClass(1, "wrap", "quux");
cls(1, null, "baz", "foo quux");
cls(1, null, "baz", "foo quux", "gutter-class");
cm.removeLineClass(1, "wrap");
cls(1, null, "baz", null);
}, {value: "hohoho\n"});
cls(1, null, "baz", null, "gutter-class");
cm.removeLineClass(1, "gutter", "gutter-class");
eq(byClassName(lines, "gutter-class").length, 0);
cls(1, null, "baz", null, null);
cm.addLineClass(1, "gutter", "gutter-class");
cls(1, null, "baz", null, "gutter-class");
cm.removeLineClass(1, "gutter", "gutter-class");
cls(1, null, "baz", null, null);
}, {value: "hohoho\n", lineNumbers: true});
testCM("atomicMarker", function(cm) {
addDoc(cm, 10, 10);
@ -1558,9 +1664,19 @@ testCM("selectionBias", function(cm) {
eqPos(cm.getCursor(), Pos(0, 1));
cm.setCursor(Pos(0, 4));
cm.setCursor(Pos(0, 2), null, {bias: 1});
eqPos(cm.getCursor(), Pos(0, 3), "A");
eqPos(cm.getCursor(), Pos(0, 3));
}, {value: "12345"});
testCM("selectionHomeEnd", function(cm) {
cm.markText(Pos(1, 0), Pos(1, 1), {atomic: true, inclusiveLeft: true});
cm.markText(Pos(1, 3), Pos(1, 4), {atomic: true, inclusiveRight: true});
cm.setCursor(Pos(1, 2));
cm.execCommand("goLineStart");
eqPos(cm.getCursor(), Pos(1, 1));
cm.execCommand("goLineEnd");
eqPos(cm.getCursor(), Pos(1, 3));
}, {value: "ab\ncdef\ngh"});
testCM("readOnlyMarker", function(cm) {
function mark(ll, cl, lr, cr, at) {
return cm.markText(Pos(ll, cl), Pos(lr, cr),
@ -1904,6 +2020,18 @@ testCM("alwaysMergeSelEventWithChangeOrigin", function(cm) {
eq(cm.getValue(), "Va");
}, {value: "a"});
testCM("getTokenAt", function(cm) {
var tokPlus = cm.getTokenAt(Pos(0, 2));
eq(tokPlus.type, "operator");
eq(tokPlus.string, "+");
var toks = cm.getLineTokens(0);
eq(toks.length, 3);
forEach([["number", "1"], ["operator", "+"], ["number", "2"]], function(expect, i) {
eq(toks[i].type, expect[0]);
eq(toks[i].string, expect[1]);
});
}, {value: "1+2", mode: "javascript"});
testCM("getTokenTypeAt", function(cm) {
eq(cm.getTokenTypeAt(Pos(0, 0)), "number");
eq(cm.getTokenTypeAt(Pos(0, 6)), "string");
@ -1916,3 +2044,99 @@ testCM("getTokenTypeAt", function(cm) {
eq(byClassName(cm.getWrapperElement(), "cm-foo").length, 1);
eq(cm.getTokenTypeAt(Pos(0, 6)), "string");
}, {value: "1 + 'foo'", mode: "javascript"});
testCM("resizeLineWidget", function(cm) {
addDoc(cm, 200, 3);
var widget = document.createElement("pre");
widget.innerHTML = "imwidget";
widget.style.background = "yellow";
cm.addLineWidget(1, widget, {noHScroll: true});
cm.setSize(40);
is(widget.parentNode.offsetWidth < 42);
});
testCM("combinedOperations", function(cm) {
var place = document.getElementById("testground");
var other = CodeMirror(place, {value: "123"});
try {
cm.operation(function() {
cm.addLineClass(0, "wrap", "foo");
other.addLineClass(0, "wrap", "foo");
});
eq(byClassName(cm.getWrapperElement(), "foo").length, 1);
eq(byClassName(other.getWrapperElement(), "foo").length, 1);
cm.operation(function() {
cm.removeLineClass(0, "wrap", "foo");
other.removeLineClass(0, "wrap", "foo");
});
eq(byClassName(cm.getWrapperElement(), "foo").length, 0);
eq(byClassName(other.getWrapperElement(), "foo").length, 0);
} finally {
place.removeChild(other.getWrapperElement());
}
}, {value: "abc"});
testCM("eventOrder", function(cm) {
var seen = [];
cm.on("change", function() {
if (!seen.length) cm.replaceSelection(".");
seen.push("change");
});
cm.on("cursorActivity", function() {
cm.replaceSelection("!");
seen.push("activity");
});
cm.replaceSelection("/");
eq(seen.join(","), "change,change,activity,change");
});
testCM("splitSpaces_nonspecial", function(cm) {
eq(byClassName(cm.getWrapperElement(), "cm-invalidchar").length, 0);
}, {
specialChars: /[\u00a0]/,
value: "spaces -> <- between"
});
test("core_rmClass", function() {
var node = document.createElement("div");
node.className = "foo-bar baz-quux yadda";
CodeMirror.rmClass(node, "quux");
eq(node.className, "foo-bar baz-quux yadda");
CodeMirror.rmClass(node, "baz-quux");
eq(node.className, "foo-bar yadda");
CodeMirror.rmClass(node, "yadda");
eq(node.className, "foo-bar");
CodeMirror.rmClass(node, "foo-bar");
eq(node.className, "");
node.className = " foo ";
CodeMirror.rmClass(node, "foo");
eq(node.className, "");
});
test("core_addClass", function() {
var node = document.createElement("div");
CodeMirror.addClass(node, "a");
eq(node.className, "a");
CodeMirror.addClass(node, "a");
eq(node.className, "a");
CodeMirror.addClass(node, "b");
eq(node.className, "a b");
CodeMirror.addClass(node, "a");
CodeMirror.addClass(node, "b");
eq(node.className, "a b");
});
testCM("lineSeparator", function(cm) {
eq(cm.lineCount(), 3);
eq(cm.getLine(1), "bar\r");
eq(cm.getLine(2), "baz\rquux");
cm.setOption("lineSeparator", "\r");
eq(cm.lineCount(), 5);
eq(cm.getLine(4), "quux");
eq(cm.getValue(), "foo\rbar\r\rbaz\rquux");
eq(cm.getValue("\n"), "foo\nbar\n\nbaz\nquux");
cm.setOption("lineSeparator", null);
cm.setValue("foo\nbar\r\nbaz\rquux");
eq(cm.lineCount(), 4);
}, {value: "foo\nbar\r\nbaz\rquux",
lineSeparator: "\n"});

1064
devtools/client/sourceeditor/test/codemirror/vim_test.js Normal file → Executable file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -116,7 +116,8 @@
running = false, // Flag that states tests are running
quit = false, // Flag to quit tests ASAP
verbose = false, // Adds message for *every* test to output
phantom = false;
phantom = false,
Pos = CodeMirror.Pos; // Required for VIM tests
function runHarness(){
if (running) {

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

@ -30,7 +30,7 @@ const SAVE_ERROR = "error-save";
// max update frequency in ms (avoid potential typing lag and/or flicker)
// @see StyleEditor.updateStylesheet
const UPDATE_STYLESHEET_THROTTLE_DELAY = 500;
const UPDATE_STYLESHEET_DELAY = 500;
// Pref which decides if CSS autocompletion is enabled in Style Editor or not.
const AUTOCOMPLETION_PREF = "devtools.styleeditor.autocompletion-enabled";
@ -108,6 +108,7 @@ function StyleSheetEditor(styleSheet, win, file, isNew, walker, highlighter) {
this.markLinkedFileBroken = this.markLinkedFileBroken.bind(this);
this.saveToFile = this.saveToFile.bind(this);
this.updateStyleSheet = this.updateStyleSheet.bind(this);
this._updateStyleSheet = this._updateStyleSheet.bind(this);
this._onMouseMove = this._onMouseMove.bind(this);
this._focusOnSourceEditorReady = false;
@ -469,22 +470,15 @@ StyleSheetEditor.prototype = {
/**
* Queue a throttled task to update the live style sheet.
*
* @param boolean immediate
* Optional. If true the update is performed immediately.
*/
updateStyleSheet: function(immediate) {
updateStyleSheet: function() {
if (this._updateTask) {
// cancel previous queued task not executed within throttle delay
this._window.clearTimeout(this._updateTask);
}
if (immediate) {
this._updateStyleSheet();
} else {
this._updateTask = this._window.setTimeout(this._updateStyleSheet.bind(this),
UPDATE_STYLESHEET_THROTTLE_DELAY);
}
this._updateTask = this._window.setTimeout(this._updateStyleSheet,
UPDATE_STYLESHEET_DELAY);
},
/**

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

@ -49,7 +49,7 @@ function* testPressingEscapeRevertsChanges(view) {
yield ruleEditor.rule._applyingModifications;
yield waitForComputedStyleProperty("body", null, "animation-timing-function",
"cubic-bezier(0, 0, 1, 1)");
"linear");
is(propEditor.valueSpan.textContent, "linear",
"Got expected property value.");
}

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

@ -10,6 +10,8 @@ const URL2 = MAIN_DOMAIN + "navigate-second.html";
var events = require("sdk/event/core");
var client;
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
// State machine to check events order
var i = 0;
function assertEvent(event, data) {

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

@ -6,6 +6,8 @@ var stayingOnPage = true;
var TEST_PAGE = "http://mochi.test:8888/browser/docshell/test/browser/file_bug1046022.html";
var TARGETED_PAGE = "data:text/html," + encodeURIComponent("<body>Shouldn't be seeing this</body>");
SpecialPowers.pushPrefEnv({"set": [["dom.require_user_interaction_for_beforeunload", false]]});
var loadExpected = TEST_PAGE;
var testTab;

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

@ -10,6 +10,7 @@
#include "AnimationCommon.h"
#include "nsCSSPropertySet.h"
#include "nsCSSProps.h" // For nsCSSProps::PropHasFlags
#include "nsStyleUtil.h"
namespace mozilla {
@ -17,11 +18,12 @@ void
ComputedTimingFunction::Init(const nsTimingFunction &aFunction)
{
mType = aFunction.mType;
if (mType == nsTimingFunction::Function) {
if (nsTimingFunction::IsSplineType(mType)) {
mTimingFunction.Init(aFunction.mFunc.mX1, aFunction.mFunc.mY1,
aFunction.mFunc.mX2, aFunction.mFunc.mY2);
} else {
mSteps = aFunction.mSteps;
mStepSyntax = aFunction.mStepSyntax;
}
}
@ -35,23 +37,67 @@ StepEnd(uint32_t aSteps, double aPortion)
double
ComputedTimingFunction::GetValue(double aPortion) const
{
if (HasSpline()) {
return mTimingFunction.GetSplineValue(aPortion);
}
if (mType == nsTimingFunction::Type::StepStart) {
// There are diagrams in the spec that seem to suggest this check
// and the bounds point should not be symmetric with StepEnd, but
// should actually step up at rather than immediately after the
// fraction points. However, we rely on rounding negative values
// up to zero, so we can't do that. And it's not clear the spec
// really meant it.
return 1.0 - StepEnd(mSteps, 1.0 - aPortion);
}
MOZ_ASSERT(mType == nsTimingFunction::Type::StepEnd, "bad type");
return StepEnd(mSteps, aPortion);
}
int32_t
ComputedTimingFunction::Compare(const ComputedTimingFunction& aRhs) const
{
if (mType != aRhs.mType) {
return int32_t(mType) - int32_t(aRhs.mType);
}
if (mType == nsTimingFunction::Type::CubicBezier) {
int32_t order = mTimingFunction.Compare(aRhs.mTimingFunction);
if (order != 0) {
return order;
}
} else if (mType == nsTimingFunction::Type::StepStart ||
mType == nsTimingFunction::Type::StepEnd) {
if (mSteps != aRhs.mSteps) {
return int32_t(mSteps) - int32_t(aRhs.mSteps);
}
if (mStepSyntax != aRhs.mStepSyntax) {
return int32_t(mStepSyntax) - int32_t(aRhs.mStepSyntax);
}
}
return 0;
}
void
ComputedTimingFunction::AppendToString(nsAString& aResult) const
{
switch (mType) {
case nsTimingFunction::Function:
return mTimingFunction.GetSplineValue(aPortion);
case nsTimingFunction::StepStart:
// There are diagrams in the spec that seem to suggest this check
// and the bounds point should not be symmetric with StepEnd, but
// should actually step up at rather than immediately after the
// fraction points. However, we rely on rounding negative values
// up to zero, so we can't do that. And it's not clear the spec
// really meant it.
return 1.0 - StepEnd(mSteps, 1.0 - aPortion);
case nsTimingFunction::Type::CubicBezier:
nsStyleUtil::AppendCubicBezierTimingFunction(mTimingFunction.X1(),
mTimingFunction.Y1(),
mTimingFunction.X2(),
mTimingFunction.Y2(),
aResult);
break;
case nsTimingFunction::Type::StepStart:
case nsTimingFunction::Type::StepEnd:
nsStyleUtil::AppendStepsTimingFunction(mType, mSteps, mStepSyntax,
aResult);
break;
default:
MOZ_ASSERT(false, "bad type");
// fall through
case nsTimingFunction::StepEnd:
return StepEnd(mSteps, aPortion);
nsStyleUtil::AppendCubicBezierKeywordTimingFunction(mType, aResult);
break;
}
}
@ -456,5 +502,116 @@ KeyframeEffectReadOnly::ResetIsRunningOnCompositor()
}
}
struct KeyframeValueEntry
{
float mOffset;
nsCSSProperty mProperty;
nsString mValue;
const ComputedTimingFunction* mTimingFunction;
bool operator==(const KeyframeValueEntry& aRhs) const
{
NS_ASSERTION(mOffset != aRhs.mOffset || mProperty != aRhs.mProperty,
"shouldn't have duplicate (offset, property) pairs");
return false;
}
bool operator<(const KeyframeValueEntry& aRhs) const
{
NS_ASSERTION(mOffset != aRhs.mOffset || mProperty != aRhs.mProperty,
"shouldn't have duplicate (offset, property) pairs");
// First, sort by offset.
if (mOffset != aRhs.mOffset) {
return mOffset < aRhs.mOffset;
}
// Second, by timing function.
int32_t order = mTimingFunction->Compare(*aRhs.mTimingFunction);
if (order != 0) {
return order < 0;
}
// Last, by property IDL name.
return nsCSSProps::PropertyIDLNameSortPosition(mProperty) <
nsCSSProps::PropertyIDLNameSortPosition(aRhs.mProperty);
}
};
void
KeyframeEffectReadOnly::GetFrames(JSContext*& aCx,
nsTArray<JSObject*>& aResult,
ErrorResult& aRv)
{
// Collect tuples of the form (offset, property, value, easing) from
// mProperties, then sort them so we can generate one ComputedKeyframe per
// offset/easing pair. We sort secondarily by property IDL name so that we
// have a uniform order that we set properties on the ComputedKeyframe
// object.
nsAutoTArray<KeyframeValueEntry,4> entries;
for (const AnimationProperty& property : mProperties) {
if (property.mSegments.IsEmpty()) {
continue;
}
for (size_t i = 0, n = property.mSegments.Length(); i < n; i++) {
const AnimationPropertySegment& segment = property.mSegments[i];
KeyframeValueEntry* entry = entries.AppendElement();
entry->mOffset = segment.mFromKey;
entry->mProperty = property.mProperty;
entry->mTimingFunction = &segment.mTimingFunction;
StyleAnimationValue::UncomputeValue(property.mProperty,
segment.mFromValue,
entry->mValue);
}
const AnimationPropertySegment& segment = property.mSegments.LastElement();
KeyframeValueEntry* entry = entries.AppendElement();
entry->mOffset = segment.mToKey;
entry->mProperty = property.mProperty;
// We don't have the an appropriate animation-timing-function value to use,
// either from the element or from the 100% keyframe, so we just set it to
// the animation-timing-value value used on the previous segment.
entry->mTimingFunction = &segment.mTimingFunction;
StyleAnimationValue::UncomputeValue(property.mProperty,
segment.mToValue,
entry->mValue);
}
entries.Sort();
for (size_t i = 0, n = entries.Length(); i < n; ) {
// Create a JS object with the explicit ComputedKeyframe dictionary members.
ComputedKeyframe keyframeDict;
keyframeDict.mOffset.SetValue(entries[i].mOffset);
keyframeDict.mComputedOffset.Construct(entries[i].mOffset);
keyframeDict.mEasing.Truncate();
entries[i].mTimingFunction->AppendToString(keyframeDict.mEasing);
keyframeDict.mComposite.SetValue(CompositeOperation::Replace);
JS::Rooted<JS::Value> keyframeValue(aCx);
if (!ToJSValue(aCx, keyframeDict, &keyframeValue)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
JS::Rooted<JSObject*> keyframe(aCx, &keyframeValue.toObject());
// Set the property name/value pairs on the JS object.
do {
const KeyframeValueEntry& entry = entries[i];
const char* name = nsCSSProps::PropertyIDLName(entry.mProperty);
JS::Rooted<JS::Value> value(aCx);
if (!ToJSValue(aCx, entry.mValue, &value) ||
!JS_DefineProperty(aCx, keyframe, name, value, JSPROP_ENUMERATE)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
++i;
} while (i < n &&
entries[i].mOffset == entries[i - 1].mOffset &&
*entries[i].mTimingFunction == *entries[i - 1].mTimingFunction);
aResult.AppendElement(keyframe);
}
}
} // namespace dom
} // namespace mozilla

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

@ -19,6 +19,7 @@
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/AnimationEffectReadOnly.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/KeyframeBinding.h"
#include "mozilla/dom/Nullable.h"
#include "nsSMILKeySpline.h"
#include "nsStyleStruct.h" // for nsTimingFunction
@ -109,28 +110,35 @@ class ComputedTimingFunction
{
public:
typedef nsTimingFunction::Type Type;
typedef nsTimingFunction::StepSyntax StepSyntax;
void Init(const nsTimingFunction &aFunction);
double GetValue(double aPortion) const;
const nsSMILKeySpline* GetFunction() const {
NS_ASSERTION(mType == nsTimingFunction::Function, "Type mismatch");
NS_ASSERTION(HasSpline(), "Type mismatch");
return &mTimingFunction;
}
Type GetType() const { return mType; }
bool HasSpline() const { return nsTimingFunction::IsSplineType(mType); }
uint32_t GetSteps() const { return mSteps; }
StepSyntax GetStepSyntax() const { return mStepSyntax; }
bool operator==(const ComputedTimingFunction& aOther) const {
return mType == aOther.mType &&
(mType == nsTimingFunction::Function ?
(HasSpline() ?
mTimingFunction == aOther.mTimingFunction :
mSteps == aOther.mSteps);
(mSteps == aOther.mSteps &&
mStepSyntax == aOther.mStepSyntax));
}
bool operator!=(const ComputedTimingFunction& aOther) const {
return !(*this == aOther);
}
int32_t Compare(const ComputedTimingFunction& aRhs) const;
void AppendToString(nsAString& aResult) const;
private:
Type mType;
nsSMILKeySpline mTimingFunction;
uint32_t mSteps;
StepSyntax mStepSyntax;
};
struct AnimationPropertySegment
@ -225,6 +233,9 @@ public:
" pseudo-element is not yet supported.");
return mTarget;
}
void GetFrames(JSContext*& aCx,
nsTArray<JSObject*>& aResult,
ErrorResult& aRv);
// Temporary workaround to return both the target element and pseudo-type
// until we implement PseudoElement (bug 1174575).

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

@ -30,8 +30,11 @@ UNIFIED_SOURCES += [
'PendingAnimationTracker.cpp',
]
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/dom/base',
]
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше