зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to b2g-inbound.
This commit is contained in:
Коммит
2a34efc421
|
@ -1330,9 +1330,11 @@ pref("devtools.tilt.outro_transition", true);
|
|||
// 'Open Recent'-menu.
|
||||
// - showTrailingSpace: Whether to highlight trailing space or not.
|
||||
// - enableCodeFolding: Whether to enable code folding or not.
|
||||
// - enableAutocompletion: Whether to enable JavaScript autocompletion.
|
||||
pref("devtools.scratchpad.recentFilesMax", 10);
|
||||
pref("devtools.scratchpad.showTrailingSpace", false);
|
||||
pref("devtools.scratchpad.enableCodeFolding", true);
|
||||
pref("devtools.scratchpad.enableAutocompletion", true);
|
||||
|
||||
// Enable the Style Editor.
|
||||
pref("devtools.styleeditor.enabled", true);
|
||||
|
|
|
@ -566,6 +566,8 @@ var FullScreen = {
|
|||
navbar.appendChild(fullscreenctls);
|
||||
}
|
||||
fullscreenctls.hidden = aShow;
|
||||
|
||||
ToolbarIconColor.inferFromText();
|
||||
}
|
||||
};
|
||||
XPCOMUtils.defineLazyGetter(FullScreen, "useLionFullScreen", function() {
|
||||
|
|
|
@ -69,7 +69,7 @@ SocialUI = {
|
|||
Services.prefs.addObserver("social.toast-notifications.enabled", this, false);
|
||||
|
||||
gBrowser.addEventListener("ActivateSocialFeature", this._activationEventHandler.bind(this), true, true);
|
||||
document.getElementById("PanelUI-popup").addEventListener("popupshown", SocialMarks.updatePanelButtons, true);
|
||||
PanelUI.panel.addEventListener("popupshown", SocialUI.updateState, true);
|
||||
|
||||
// menupopups that list social providers. we only populate them when shown,
|
||||
// and if it has not been done already.
|
||||
|
@ -102,7 +102,7 @@ SocialUI = {
|
|||
|
||||
Services.prefs.removeObserver("social.toast-notifications.enabled", this);
|
||||
|
||||
document.getElementById("PanelUI-popup").removeEventListener("popupshown", SocialMarks.updatePanelButtons, true);
|
||||
PanelUI.panel.removeEventListener("popupshown", SocialUI.updateState, true);
|
||||
document.getElementById("viewSidebarMenu").removeEventListener("popupshowing", SocialSidebar.populateSidebarMenu, true);
|
||||
document.getElementById("social-statusarea-popup").removeEventListener("popupshowing", SocialSidebar.populateSidebarMenu, true);
|
||||
|
||||
|
@ -288,7 +288,7 @@ SocialUI = {
|
|||
// called on tab/urlbar/location changes and after customization. Update
|
||||
// anything that is tab specific.
|
||||
updateState: function() {
|
||||
if (!this.enabled)
|
||||
if (!SocialUI.enabled)
|
||||
return;
|
||||
SocialMarks.update();
|
||||
SocialShare.update();
|
||||
|
@ -432,6 +432,12 @@ SocialFlyout = {
|
|||
}
|
||||
|
||||
SocialShare = {
|
||||
// Share panel may be attached to the overflow or menu button depending on
|
||||
// customization, we need to manage open state of the anchor.
|
||||
get anchor() {
|
||||
let widget = CustomizableUI.getWidget("social-share-button");
|
||||
return widget.forWindow(window).anchor;
|
||||
},
|
||||
get panel() {
|
||||
return document.getElementById("social-share-panel");
|
||||
},
|
||||
|
@ -523,7 +529,15 @@ SocialShare = {
|
|||
},
|
||||
|
||||
get shareButton() {
|
||||
return document.getElementById("social-share-button");
|
||||
// web-panels (bookmark/sidebar) don't include customizableui, so
|
||||
// nsContextMenu fails when accessing shareButton, breaking
|
||||
// browser_bug409481.js.
|
||||
if (!window.CustomizableUI)
|
||||
return null;
|
||||
let widget = CustomizableUI.getWidget("social-share-button");
|
||||
if (!widget || !widget.areaType)
|
||||
return null;
|
||||
return widget.forWindow(window).node;
|
||||
},
|
||||
|
||||
canSharePage: function(aURI) {
|
||||
|
@ -540,23 +554,29 @@ SocialShare = {
|
|||
let shareButton = this.shareButton;
|
||||
shareButton.hidden = !SocialUI.enabled ||
|
||||
[p for (p of Social.providers) if (p.shareURL)].length == 0;
|
||||
shareButton.disabled = shareButton.hidden || !this.canSharePage(gBrowser.currentURI);
|
||||
let disabled = shareButton.hidden || !this.canSharePage(gBrowser.currentURI);
|
||||
|
||||
// also update the relevent command's disabled state so the keyboard
|
||||
// 1. update the relevent command's disabled state so the keyboard
|
||||
// shortcut only works when available.
|
||||
// 2. If the button has been relocated to a place that is not visible by
|
||||
// default (e.g. menu panel) then the disabled attribute will not update
|
||||
// correctly based on the command, so we update the attribute directly as.
|
||||
let cmd = document.getElementById("Social:SharePage");
|
||||
if (shareButton.disabled)
|
||||
if (disabled) {
|
||||
cmd.setAttribute("disabled", "true");
|
||||
else
|
||||
shareButton.setAttribute("disabled", "true");
|
||||
} else {
|
||||
cmd.removeAttribute("disabled");
|
||||
shareButton.removeAttribute("disabled");
|
||||
}
|
||||
},
|
||||
|
||||
onShowing: function() {
|
||||
this.shareButton.setAttribute("open", "true");
|
||||
this.anchor.setAttribute("open", "true");
|
||||
},
|
||||
|
||||
onHidden: function() {
|
||||
this.shareButton.removeAttribute("open");
|
||||
this.anchor.removeAttribute("open");
|
||||
this.iframe.setAttribute("src", "data:text/plain;charset=utf8,");
|
||||
this.currentShare = null;
|
||||
},
|
||||
|
@ -670,8 +690,7 @@ SocialShare = {
|
|||
iframe.setAttribute("origin", provider.origin);
|
||||
iframe.setAttribute("src", shareEndpoint);
|
||||
|
||||
let navBar = document.getElementById("nav-bar");
|
||||
let anchor = document.getAnonymousElementByAttribute(this.shareButton, "class", "toolbarbutton-icon");
|
||||
let anchor = document.getAnonymousElementByAttribute(this.anchor, "class", "toolbarbutton-icon");
|
||||
this.panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
|
||||
Social.setErrorListener(iframe, this.setErrorMessage.bind(this));
|
||||
}
|
||||
|
@ -1357,7 +1376,6 @@ SocialMarks = {
|
|||
// querySelectorAll does not work on the menu panel the panel, so we have to
|
||||
// do this the hard way.
|
||||
let providers = SocialMarks.getProviders();
|
||||
let panel = document.getElementById("PanelUI-popup");
|
||||
for (let p of providers) {
|
||||
let widgetId = SocialMarks._toolbarHelper.idFromOrigin(p.origin);
|
||||
let widget = CustomizableUI.getWidget(widgetId);
|
||||
|
|
|
@ -947,6 +947,8 @@ var gBrowserInit = {
|
|||
}
|
||||
#endif
|
||||
|
||||
ToolbarIconColor.init();
|
||||
|
||||
// Wait until chrome is painted before executing code not critical to making the window visible
|
||||
this._boundDelayedStartup = this._delayedStartup.bind(this, mustLoadSidebar);
|
||||
window.addEventListener("MozAfterPaint", this._boundDelayedStartup);
|
||||
|
@ -1283,6 +1285,8 @@ var gBrowserInit = {
|
|||
|
||||
TabsInTitlebar.uninit();
|
||||
|
||||
ToolbarIconColor.uninit();
|
||||
|
||||
var enumerator = Services.wm.getEnumerator(null);
|
||||
enumerator.getNext();
|
||||
if (!enumerator.hasMoreElements()) {
|
||||
|
@ -4296,6 +4300,8 @@ function setToolbarVisibility(toolbar, isVisible, persist=true) {
|
|||
PlacesToolbarHelper.init();
|
||||
BookmarkingUI.onToolbarVisibilityChange();
|
||||
gBrowser.updateWindowResizers();
|
||||
if (isVisible)
|
||||
ToolbarIconColor.inferFromText();
|
||||
}
|
||||
|
||||
var TabsInTitlebar = {
|
||||
|
@ -4540,6 +4546,8 @@ var TabsInTitlebar = {
|
|||
titlebar.style.marginBottom = "";
|
||||
menubar.style.paddingBottom = "";
|
||||
}
|
||||
|
||||
ToolbarIconColor.inferFromText();
|
||||
},
|
||||
|
||||
_sizePlaceholder: function (type, width) {
|
||||
|
@ -7192,3 +7200,71 @@ function BrowserOpenNewTabOrWindow(event) {
|
|||
BrowserOpenTab();
|
||||
}
|
||||
}
|
||||
|
||||
let ToolbarIconColor = {
|
||||
init: function () {
|
||||
this._initialized = true;
|
||||
|
||||
window.addEventListener("activate", this);
|
||||
window.addEventListener("deactivate", this);
|
||||
Services.obs.addObserver(this, "lightweight-theme-styling-update", false);
|
||||
|
||||
// If the window isn't active now, we assume that it has never been active
|
||||
// before and will soon become active such that inferFromText will be
|
||||
// called from the initial activate event.
|
||||
if (Services.focus.activeWindow == window)
|
||||
this.inferFromText();
|
||||
},
|
||||
|
||||
uninit: function () {
|
||||
this._initialized = false;
|
||||
|
||||
window.removeEventListener("activate", this);
|
||||
window.removeEventListener("deactivate", this);
|
||||
Services.obs.removeObserver(this, "lightweight-theme-styling-update");
|
||||
},
|
||||
|
||||
handleEvent: function (event) {
|
||||
switch (event.type) {
|
||||
case "activate":
|
||||
case "deactivate":
|
||||
this.inferFromText();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "lightweight-theme-styling-update":
|
||||
// inferFromText needs to run after LightweightThemeConsumer.jsm's
|
||||
// lightweight-theme-styling-update observer.
|
||||
setTimeout(() => { this.inferFromText(); }, 0);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
inferFromText: function () {
|
||||
if (!this._initialized)
|
||||
return;
|
||||
|
||||
function parseRGB(aColorString) {
|
||||
let rgb = aColorString.match(/^rgba?\((\d+), (\d+), (\d+)/);
|
||||
rgb.shift();
|
||||
return rgb.map(x => parseInt(x));
|
||||
}
|
||||
|
||||
let toolbarSelector = "#navigator-toolbox > toolbar:not([collapsed=true]):not(#addon-bar)";
|
||||
#ifdef XP_MACOSX
|
||||
toolbarSelector += ":not([type=menubar])";
|
||||
#endif
|
||||
|
||||
for (let toolbar of document.querySelectorAll(toolbarSelector)) {
|
||||
let [r, g, b] = parseRGB(getComputedStyle(toolbar).color);
|
||||
let luminance = 0.2125 * r + 0.7154 * g + 0.0721 * b;
|
||||
if (luminance <= 110)
|
||||
toolbar.removeAttribute("brighttext");
|
||||
else
|
||||
toolbar.setAttribute("brighttext", "true");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -899,10 +899,10 @@
|
|||
<toolbarbutton id="social-share-button"
|
||||
class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
hidden="true"
|
||||
overflows="false"
|
||||
label="&sharePageCmd.label;"
|
||||
tooltiptext="&sharePageCmd.label;"
|
||||
cui-areatype="toolbar"
|
||||
removable="true"
|
||||
command="Social:SharePage"/>
|
||||
</hbox>
|
||||
|
||||
|
|
|
@ -10,8 +10,6 @@ Cu.import("resource://gre/modules/Services.jsm");
|
|||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ContentLinkHandler",
|
||||
"resource:///modules/ContentLinkHandler.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LanguageDetector",
|
||||
"resource:///modules/translation/LanguageDetector.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerContent",
|
||||
"resource://gre/modules/LoginManagerContent.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "InsecurePasswordUtils",
|
||||
|
@ -442,51 +440,9 @@ let PageStyleHandler = {
|
|||
};
|
||||
PageStyleHandler.init();
|
||||
|
||||
let TranslationHandler = {
|
||||
init: function() {
|
||||
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
|
||||
},
|
||||
|
||||
/* nsIWebProgressListener implementation */
|
||||
onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
// Don't bother if we're not a toplevel document, if this isn't the 'stop'
|
||||
// notification, or if the content document has gone away
|
||||
if (!aWebProgress.isTopLevel ||
|
||||
!(aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) ||
|
||||
!content)
|
||||
return;
|
||||
|
||||
let url = aRequest.name;
|
||||
if (!url.startsWith("http://") && !url.startsWith("https://"))
|
||||
return;
|
||||
|
||||
// Grab a 60k sample of text from the page.
|
||||
let encoder = Cc["@mozilla.org/layout/documentEncoder;1?type=text/plain"]
|
||||
.createInstance(Ci.nsIDocumentEncoder);
|
||||
encoder.init(content.document, "text/plain", encoder.SkipInvisibleContent);
|
||||
let string = encoder.encodeToStringWithMaxLength(60 * 1024);
|
||||
|
||||
// Language detection isn't reliable on very short strings.
|
||||
if (string.length < 100)
|
||||
return;
|
||||
|
||||
LanguageDetector.detectLanguage(string).then(result => {
|
||||
if (result.confident)
|
||||
sendAsyncMessage("LanguageDetection:Result", result.language);
|
||||
});
|
||||
},
|
||||
|
||||
// Unused methods.
|
||||
onProgressChange: function() {},
|
||||
onLocationChange: function() {},
|
||||
onStatusChange: function() {},
|
||||
onSecurityChange: function() {},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
|
||||
Ci.nsISupportsWeakReference])
|
||||
};
|
||||
|
||||
if (Services.prefs.getBoolPref("browser.translation.detectLanguage"))
|
||||
TranslationHandler.init();
|
||||
// Keep a reference to the translation content handler to avoid it it being GC'ed.
|
||||
let trHandler = null;
|
||||
if (Services.prefs.getBoolPref("browser.translation.detectLanguage")) {
|
||||
Cu.import("resource:///modules/translation/TranslationContentHandler.jsm");
|
||||
trHandler = new TranslationContentHandler(global, docShell);
|
||||
}
|
||||
|
|
|
@ -3414,7 +3414,7 @@ let SessionStoreInternal = {
|
|||
* with respect to |browser|.
|
||||
*/
|
||||
isCurrentEpoch: function (browser, epoch) {
|
||||
return this._browserEpochs.get(browser.permanentKey, 0) == epoch;
|
||||
return (this._browserEpochs.get(browser.permanentKey) || 0) == epoch;
|
||||
},
|
||||
|
||||
};
|
||||
|
|
|
@ -0,0 +1,370 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "BingTranslation" ];
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Log.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://services-common/utils.js");
|
||||
Cu.import("resource://services-common/rest.js");
|
||||
|
||||
// The maximum amount of net data allowed per request on Bing's API.
|
||||
const MAX_REQUEST_DATA = 5000; // Documentation says 10000 but anywhere
|
||||
// close to that is refused by the service.
|
||||
|
||||
// The maximum number of chunks allowed to be translated in a single
|
||||
// request.
|
||||
const MAX_REQUEST_CHUNKS = 1000; // Documentation says 2000.
|
||||
|
||||
// Self-imposed limit of 15 requests. This means that a page that would need
|
||||
// to be broken in more than 15 requests won't be fully translated.
|
||||
// The maximum amount of data that we will translate for a single page
|
||||
// is MAX_REQUESTS * MAX_REQUEST_DATA.
|
||||
const MAX_REQUESTS = 15;
|
||||
|
||||
/**
|
||||
* Translates a webpage using Bing's Translation API.
|
||||
*
|
||||
* @param translationDocument The TranslationDocument object that represents
|
||||
* the webpage to be translated
|
||||
* @param sourceLanguage The source language of the document
|
||||
* @param targetLanguage The target language for the translation
|
||||
*
|
||||
* @returns {Promise} A promise that will resolve when the translation
|
||||
* task is finished.
|
||||
*/
|
||||
this.BingTranslation = function(translationDocument, sourceLanguage, targetLanguage) {
|
||||
this.translationDocument = translationDocument;
|
||||
this.sourceLanguage = sourceLanguage;
|
||||
this.targetLanguage = targetLanguage;
|
||||
this._pendingRequests = 0;
|
||||
this._partialSuccess = false;
|
||||
};
|
||||
|
||||
this.BingTranslation.prototype = {
|
||||
/**
|
||||
* Performs the translation, splitting the document into several chunks
|
||||
* respecting the data limits of the API.
|
||||
*
|
||||
* @returns {Promise} A promise that will resolve when the translation
|
||||
* task is finished.
|
||||
*/
|
||||
translate: function() {
|
||||
return Task.spawn(function *() {
|
||||
let currentIndex = 0;
|
||||
this._onFinishedDeferred = Promise.defer();
|
||||
|
||||
// Let's split the document into various requests to be sent to
|
||||
// Bing's Translation API.
|
||||
for (let requestCount = 0; requestCount < MAX_REQUESTS; requestCount++) {
|
||||
// Generating the text for each request can be expensive, so
|
||||
// let's take the opportunity of the chunkification process to
|
||||
// allow for the event loop to attend other pending events
|
||||
// before we continue.
|
||||
yield CommonUtils.laterTickResolvingPromise();
|
||||
|
||||
// Determine the data for the next request.
|
||||
let request = this._generateNextTranslationRequest(currentIndex);
|
||||
|
||||
// Create a real request to the server, and put it on the
|
||||
// pending requests list.
|
||||
let bingRequest = new BingRequest(request.data,
|
||||
this.sourceLanguage,
|
||||
this.targetLanguage);
|
||||
this._pendingRequests++;
|
||||
bingRequest.fireRequest().then(this._chunkCompleted.bind(this));
|
||||
|
||||
currentIndex = request.lastIndex;
|
||||
if (request.finished) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this._onFinishedDeferred.promise;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Function called when a request sent to the server is completed.
|
||||
* This function handles determining if the response was successful or not,
|
||||
* calling the function to parse the result, and resolving the promise
|
||||
* returned by the public `translate()` method when all chunks are completed.
|
||||
*
|
||||
* @param request The BingRequest sent to the server.
|
||||
*/
|
||||
_chunkCompleted: function(bingRequest) {
|
||||
this._pendingRequests--;
|
||||
if (bingRequest.requestSucceeded &&
|
||||
this._parseChunkResult(bingRequest)) {
|
||||
// error on request
|
||||
this._partialSuccess = true;
|
||||
}
|
||||
|
||||
// Check if all pending requests have been
|
||||
// completed and then resolves the promise.
|
||||
// If at least one chunk was successful, the
|
||||
// promise will be resolved positively which will
|
||||
// display the "Success" state for the infobar. Otherwise,
|
||||
// the "Error" state will appear.
|
||||
if (this._pendingRequests == 0) {
|
||||
if (this._partialSuccess) {
|
||||
this._onFinishedDeferred.resolve("success");
|
||||
} else {
|
||||
this._onFinishedDeferred.reject("failure");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This function parses the result returned by Bing's Http.svc API,
|
||||
* which is a XML file that contains a number of elements. To our
|
||||
* particular interest, the only part of the response that matters
|
||||
* are the <TranslatedText> nodes, which contains the resulting
|
||||
* items that were sent to be translated.
|
||||
*
|
||||
* @param request The request sent to the server.
|
||||
* @returns boolean True if parsing of this chunk was successful.
|
||||
*/
|
||||
_parseChunkResult: function(bingRequest) {
|
||||
let domParser = Cc["@mozilla.org/xmlextras/domparser;1"]
|
||||
.createInstance(Ci.nsIDOMParser);
|
||||
|
||||
let results;
|
||||
try {
|
||||
let doc = domParser.parseFromString(bingRequest.networkRequest
|
||||
.response.body, "text/xml");
|
||||
results = doc.querySelectorAll("TranslatedText");
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let len = results.length;
|
||||
if (len != bingRequest.translationData.length) {
|
||||
// This should never happen, but if the service returns a different number
|
||||
// of items (from the number of items submitted), we can't use this chunk
|
||||
// because all items would be paired incorrectly.
|
||||
return false;
|
||||
}
|
||||
|
||||
let error = false;
|
||||
for (let i = 0; i < len; i++) {
|
||||
try {
|
||||
bingRequest.translationData[i][0].parseResult(
|
||||
results[i].firstChild.nodeValue
|
||||
);
|
||||
} catch (e) { error = true; }
|
||||
}
|
||||
|
||||
return !error;
|
||||
},
|
||||
|
||||
/**
|
||||
* This function will determine what is the data to be used for
|
||||
* the Nth request we are generating, based on the input params.
|
||||
*
|
||||
* @param startIndex What is the index, in the roots list, that the
|
||||
* chunk should start.
|
||||
*/
|
||||
_generateNextTranslationRequest: function(startIndex) {
|
||||
let currentDataSize = 0;
|
||||
let currentChunks = 0;
|
||||
let output = [];
|
||||
let rootsList = this.translationDocument.roots;
|
||||
|
||||
for (let i = startIndex; i < rootsList.length; i++) {
|
||||
let root = rootsList[i];
|
||||
let text = this.translationDocument.generateTextForItem(root);
|
||||
if (!text) {
|
||||
continue;
|
||||
}
|
||||
|
||||
text = escapeXML(text);
|
||||
let newCurSize = currentDataSize + text.length;
|
||||
let newChunks = currentChunks + 1;
|
||||
|
||||
if (newCurSize > MAX_REQUEST_DATA ||
|
||||
newChunks > MAX_REQUEST_CHUNKS) {
|
||||
|
||||
// If we've reached the API limits, let's stop accumulating data
|
||||
// for this request and return. We return information useful for
|
||||
// the caller to pass back on the next call, so that the function
|
||||
// can keep working from where it stopped.
|
||||
return {
|
||||
data: output,
|
||||
finished: false,
|
||||
lastIndex: i
|
||||
};
|
||||
}
|
||||
|
||||
currentDataSize = newCurSize;
|
||||
currentChunks = newChunks;
|
||||
output.push([root, text]);
|
||||
}
|
||||
|
||||
return {
|
||||
data: output,
|
||||
finished: true,
|
||||
lastIndex: 0
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a request (for 1 chunk) sent off to Bing's service.
|
||||
*
|
||||
* @params translationData The data to be used for this translation,
|
||||
* generated by the generateNextTranslationRequest...
|
||||
* function.
|
||||
* @param sourceLanguage The source language of the document.
|
||||
* @param targetLanguage The target language for the translation.
|
||||
*
|
||||
*/
|
||||
function BingRequest(translationData, sourceLanguage, targetLanguage) {
|
||||
this.translationData = translationData;
|
||||
this.sourceLanguage = sourceLanguage;
|
||||
this.targetLanguage = targetLanguage;
|
||||
}
|
||||
|
||||
BingRequest.prototype = {
|
||||
/**
|
||||
* Initiates the request
|
||||
*/
|
||||
fireRequest: function() {
|
||||
return Task.spawn(function *(){
|
||||
let token = yield BingTokenManager.getToken();
|
||||
let auth = "Bearer " + token;
|
||||
let request = new RESTRequest("https://api.microsofttranslator.com/v2/Http.svc/TranslateArray");
|
||||
request.setHeader("Content-type", "text/xml");
|
||||
request.setHeader("Authorization", auth);
|
||||
|
||||
let requestString =
|
||||
'<TranslateArrayRequest>' +
|
||||
'<AppId/>' +
|
||||
'<From>' + this.sourceLanguage + '</From>' +
|
||||
'<Options>' +
|
||||
'<ContentType xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2">text/html</ContentType>' +
|
||||
'<ReservedFlags xmlns="http://schemas.datacontract.org/2004/07/Microsoft.MT.Web.Service.V2" />' +
|
||||
'</Options>' +
|
||||
'<Texts xmlns:s="http://schemas.microsoft.com/2003/10/Serialization/Arrays">';
|
||||
|
||||
for (let [, text] of this.translationData) {
|
||||
requestString += '<s:string>' + text + '</s:string>';
|
||||
}
|
||||
|
||||
requestString += '</Texts>' +
|
||||
'<To>' + this.targetLanguage + '</To>' +
|
||||
'</TranslateArrayRequest>';
|
||||
|
||||
let utf8 = CommonUtils.encodeUTF8(requestString);
|
||||
|
||||
let deferred = Promise.defer();
|
||||
request.post(utf8, function(err) {
|
||||
deferred.resolve(this);
|
||||
}.bind(this));
|
||||
|
||||
this.networkRequest = request;
|
||||
return deferred.promise;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the request succeeded. Only valid
|
||||
* after the request has finished.
|
||||
*
|
||||
* @returns True if the request succeeded.
|
||||
*/
|
||||
get requestSucceeded() {
|
||||
return !this.networkRequest.error &&
|
||||
this.networkRequest.response.success;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Authentication Token manager for the API
|
||||
*/
|
||||
let BingTokenManager = {
|
||||
_currentToken: null,
|
||||
_currentExpiryTime: 0,
|
||||
_pendingRequest: null,
|
||||
|
||||
/**
|
||||
* Get a valid, non-expired token to be used for the API calls.
|
||||
*
|
||||
* @returns {Promise} A promise that resolves with the token
|
||||
* string once it is obtained. The token returned
|
||||
* can be the same one used in the past if it is still
|
||||
* valid.
|
||||
*/
|
||||
getToken: function() {
|
||||
if (this._pendingRequest) {
|
||||
return this._pendingRequest;
|
||||
}
|
||||
|
||||
let remainingMs = this._currentExpiryTime - new Date();
|
||||
// Our existing token is still good for more than a minute, let's use it.
|
||||
if (remainingMs > 60 * 1000) {
|
||||
return Promise.resolve(this._currentToken);
|
||||
}
|
||||
|
||||
return this._getNewToken();
|
||||
},
|
||||
|
||||
/**
|
||||
* Generates a new token from the server.
|
||||
*
|
||||
* @returns {Promise} A promise that resolves with the token
|
||||
* string once it is obtained.
|
||||
*/
|
||||
_getNewToken: function() {
|
||||
let request = new RESTRequest("https://datamarket.accesscontrol.windows.net/v2/OAuth2-13");
|
||||
request.setHeader("Content-type", "application/x-www-form-urlencoded");
|
||||
let params = [
|
||||
"grant_type=client_credentials",
|
||||
"scope=" + encodeURIComponent("http://api.microsofttranslator.com"),
|
||||
"client_id=",
|
||||
"client_secret="
|
||||
];
|
||||
|
||||
let deferred = Promise.defer();
|
||||
this._pendingRequest = deferred.promise;
|
||||
request.post(params.join("&"), function(err) {
|
||||
this._pendingRequest = null;
|
||||
|
||||
if (err) {
|
||||
deferred.reject(err);
|
||||
}
|
||||
|
||||
try {
|
||||
let json = JSON.parse(this.response.body);
|
||||
let token = json.access_token;
|
||||
let expires_in = json.expires_in;
|
||||
BingTokenManager._currentToken = token;
|
||||
BingTokenManager._currentExpiryTime = new Date(Date.now() + expires_in * 1000);
|
||||
deferred.resolve(token);
|
||||
} catch (e) {
|
||||
deferred.reject(e);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Escape a string to be valid XML content.
|
||||
*/
|
||||
function escapeXML(aStr) {
|
||||
return aStr.toString()
|
||||
.replace("&", "&", "g")
|
||||
.replace('"', """, "g")
|
||||
.replace("'", "'", "g")
|
||||
.replace("<", "<", "g")
|
||||
.replace(">", ">", "g");
|
||||
}
|
|
@ -56,6 +56,7 @@ this.Translation = {
|
|||
*/
|
||||
function TranslationUI(aBrowser) {
|
||||
this.browser = aBrowser;
|
||||
aBrowser.messageManager.addMessageListener("Translation:Finished", this);
|
||||
}
|
||||
|
||||
TranslationUI.prototype = {
|
||||
|
@ -68,6 +69,11 @@ TranslationUI.prototype = {
|
|||
this.state = this.STATE_TRANSLATING;
|
||||
this.translatedFrom = aFrom;
|
||||
this.translatedTo = aTo;
|
||||
|
||||
this.browser.messageManager.sendAsyncMessage(
|
||||
"Translation:TranslateDocument",
|
||||
{ from: aFrom, to: aTo }
|
||||
);
|
||||
},
|
||||
|
||||
showURLBarIcon: function(aTranslated) {
|
||||
|
@ -109,11 +115,13 @@ TranslationUI.prototype = {
|
|||
showOriginalContent: function() {
|
||||
this.showURLBarIcon();
|
||||
this.originalShown = true;
|
||||
this.browser.messageManager.sendAsyncMessage("Translation:ShowOriginal");
|
||||
},
|
||||
|
||||
showTranslatedContent: function() {
|
||||
this.showURLBarIcon(true);
|
||||
this.originalShown = false;
|
||||
this.browser.messageManager.sendAsyncMessage("Translation:ShowTranslation");
|
||||
},
|
||||
|
||||
get notificationBox() this.browser.ownerGlobal.gBrowser.getNotificationBox(),
|
||||
|
@ -153,5 +161,19 @@ TranslationUI.prototype = {
|
|||
return null;
|
||||
|
||||
return this.showTranslationInfoBar();
|
||||
},
|
||||
|
||||
receiveMessage: function(msg) {
|
||||
switch (msg.name) {
|
||||
case "Translation:Finished":
|
||||
if (msg.data.success) {
|
||||
this.state = this.STATE_TRANSLATED;
|
||||
this.showURLBarIcon(true);
|
||||
this.originalShown = false;
|
||||
} else {
|
||||
this.state = this.STATE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "TranslationContentHandler" ];
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LanguageDetector",
|
||||
"resource:///modules/translation/LanguageDetector.jsm");
|
||||
|
||||
this.TranslationContentHandler = function(global, docShell) {
|
||||
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
|
||||
|
||||
global.addMessageListener("Translation:TranslateDocument", this);
|
||||
global.addMessageListener("Translation:ShowTranslation", this);
|
||||
global.addMessageListener("Translation:ShowOriginal", this);
|
||||
this.global = global;
|
||||
}
|
||||
|
||||
TranslationContentHandler.prototype = {
|
||||
/* nsIWebProgressListener implementation */
|
||||
onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
if (!aWebProgress.isTopLevel ||
|
||||
!(aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) ||
|
||||
!this.global.content)
|
||||
return;
|
||||
|
||||
let url = aRequest.name;
|
||||
if (!url.startsWith("http://") && !url.startsWith("https://"))
|
||||
return;
|
||||
|
||||
// Grab a 60k sample of text from the page.
|
||||
let encoder = Cc["@mozilla.org/layout/documentEncoder;1?type=text/plain"]
|
||||
.createInstance(Ci.nsIDocumentEncoder);
|
||||
encoder.init(this.global.content.document, "text/plain", encoder.SkipInvisibleContent);
|
||||
let string = encoder.encodeToStringWithMaxLength(60 * 1024);
|
||||
|
||||
// Language detection isn't reliable on very short strings.
|
||||
if (string.length < 100)
|
||||
return;
|
||||
|
||||
LanguageDetector.detectLanguage(string).then(result => {
|
||||
if (result.confident)
|
||||
this.global.sendAsyncMessage("LanguageDetection:Result", result.language);
|
||||
});
|
||||
},
|
||||
|
||||
// Unused methods.
|
||||
onProgressChange: function() {},
|
||||
onLocationChange: function() {},
|
||||
onStatusChange: function() {},
|
||||
onSecurityChange: function() {},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
receiveMessage: function(msg) {
|
||||
switch (msg.name) {
|
||||
case "Translation:TranslateDocument":
|
||||
{
|
||||
Cu.import("resource:///modules/translation/TranslationDocument.jsm");
|
||||
Cu.import("resource:///modules/translation/BingTranslator.jsm");
|
||||
|
||||
let translationDocument = new TranslationDocument(this.global.content.document);
|
||||
let bingTranslation = new BingTranslation(translationDocument,
|
||||
msg.data.from,
|
||||
msg.data.to);
|
||||
|
||||
this.global.content.translationDocument = translationDocument;
|
||||
bingTranslation.translate().then(
|
||||
success => {
|
||||
this.global.sendAsyncMessage("Translation:Finished", {success: true});
|
||||
translationDocument.showTranslation();
|
||||
},
|
||||
error => {
|
||||
this.global.sendAsyncMessage("Translation:Finished", {success: false});
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case "Translation:ShowOriginal":
|
||||
this.global.content.translationDocument.showOriginal();
|
||||
break;
|
||||
|
||||
case "Translation:ShowTranslation":
|
||||
this.global.content.translationDocument.showTranslation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1,440 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = [ "TranslationDocument" ];
|
||||
|
||||
const SHOW_ELEMENT = Ci.nsIDOMNodeFilter.SHOW_ELEMENT;
|
||||
const SHOW_TEXT = Ci.nsIDOMNodeFilter.SHOW_TEXT;
|
||||
const TEXT_NODE = Ci.nsIDOMNode.TEXT_NODE;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://services-common/utils.js");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
|
||||
/**
|
||||
* This class represents a document that is being translated,
|
||||
* and it is responsible for parsing the document,
|
||||
* generating the data structures translation (the list of
|
||||
* translation items and roots), and managing the original
|
||||
* and translated texts on the translation items.
|
||||
*
|
||||
* @param document The document to be translated
|
||||
*/
|
||||
this.TranslationDocument = function(document) {
|
||||
this.itemsMap = new Map();
|
||||
this.roots = [];
|
||||
this._init(document);
|
||||
};
|
||||
|
||||
this.TranslationDocument.prototype = {
|
||||
/**
|
||||
* Initializes the object and populates
|
||||
* the roots lists.
|
||||
*
|
||||
* @param document The document to be translated
|
||||
*/
|
||||
_init: function(document) {
|
||||
let window = document.defaultView;
|
||||
let winUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
// Get all the translation nodes in the document's body:
|
||||
// a translation node is a node from the document which
|
||||
// contains useful content for translation, and therefore
|
||||
// must be included in the translation process.
|
||||
let nodeList = winUtils.getTranslationNodes(document.body);
|
||||
|
||||
let length = nodeList.length;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
let node = nodeList.item(i);
|
||||
let isRoot = nodeList.isTranslationRootAtIndex(i);
|
||||
|
||||
// Create a TranslationItem object for this node.
|
||||
// This function will also add it to the this.roots array.
|
||||
this._createItemForNode(node, i, isRoot);
|
||||
}
|
||||
|
||||
// At first all roots are stored in the roots list, and only after
|
||||
// the process has finished we're able to determine which roots are
|
||||
// simple, and which ones are not.
|
||||
|
||||
// A simple root is defined by a root with no children items, which
|
||||
// basically represents an element from a page with only text content
|
||||
// inside.
|
||||
|
||||
// This distinction is useful for optimization purposes: we treat a
|
||||
// simple root as plain-text in the translation process and with that
|
||||
// we are able to reduce their data payload sent to the translation service.
|
||||
|
||||
for (let root of this.roots) {
|
||||
if (root.children.length == 0 &&
|
||||
root.nodeRef.childElementCount == 0) {
|
||||
root.isSimpleRoot = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a TranslationItem object, which should be called
|
||||
* for each node returned by getTranslationNodes.
|
||||
*
|
||||
* @param node The DOM node for this item.
|
||||
* @param id A unique, numeric id for this item.
|
||||
* @parem isRoot A boolean saying whether this item is a root.
|
||||
*
|
||||
* @returns A TranslationItem object.
|
||||
*/
|
||||
_createItemForNode: function(node, id, isRoot) {
|
||||
if (this.itemsMap.has(node)) {
|
||||
return this.itemsMap.get(node);
|
||||
}
|
||||
|
||||
let item = new TranslationItem(node, id, isRoot);
|
||||
|
||||
if (isRoot) {
|
||||
// Root items do not have a parent item.
|
||||
this.roots.push(item);
|
||||
} else {
|
||||
let parentItem = this.itemsMap.get(node.parentNode);
|
||||
if (parentItem) {
|
||||
parentItem.children.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
this.itemsMap.set(node, item);
|
||||
return item;
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate the text string that represents a TranslationItem object.
|
||||
* Besides generating the string, it's also stored in the "original"
|
||||
* field of the TranslationItem object, which needs to be stored for
|
||||
* later to be used in the "Show Original" functionality.
|
||||
*
|
||||
* @param item A TranslationItem object
|
||||
*
|
||||
* @returns A string representation of the TranslationItem.
|
||||
*/
|
||||
generateTextForItem: function(item) {
|
||||
if (item.isSimpleRoot) {
|
||||
let text = item.nodeRef.firstChild.nodeValue.trim();
|
||||
item.original = [text];
|
||||
return text;
|
||||
}
|
||||
|
||||
let localName = item.isRoot ? "div" : "b";
|
||||
let str = '<' + localName + ' id="n' + item.id + '">';
|
||||
|
||||
item.original = [];
|
||||
|
||||
for (let child of item.nodeRef.childNodes) {
|
||||
if (child.nodeType == TEXT_NODE) {
|
||||
let x = child.nodeValue.trim();
|
||||
str += x;
|
||||
item.original.push(x);
|
||||
continue;
|
||||
}
|
||||
|
||||
let objInMap = this.itemsMap.get(child);
|
||||
if (objInMap) {
|
||||
// If this childNode is present in the itemsMap, it means
|
||||
// it's a translation node: it has useful content for translation.
|
||||
// In this case, we need to stringify this node.
|
||||
item.original.push(objInMap);
|
||||
str += this.generateTextForItem(objInMap);
|
||||
} else {
|
||||
// Otherwise, if this node doesn't contain any useful content,
|
||||
// we can simply replace it by a placeholder node.
|
||||
// We can't simply eliminate this node from our string representation
|
||||
// because that could change the HTML structure (e.g., it would
|
||||
// probably merge two separate text nodes).
|
||||
str += '<br/>';
|
||||
}
|
||||
}
|
||||
|
||||
str += '</' + localName + '>';
|
||||
return str;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the document to display its translated
|
||||
* content.
|
||||
*/
|
||||
showTranslation: function() {
|
||||
this._swapDocumentContent("translation");
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the document to display its original
|
||||
* content.
|
||||
*/
|
||||
showOriginal: function() {
|
||||
this._swapDocumentContent("original");
|
||||
},
|
||||
|
||||
/**
|
||||
* Swap the document with the resulting translation,
|
||||
* or back with the original content.
|
||||
*
|
||||
* @param target A string that is either "translation"
|
||||
* or "original".
|
||||
*/
|
||||
_swapDocumentContent: function(target) {
|
||||
Task.spawn(function *() {
|
||||
// Let the event loop breath on every 100 nodes
|
||||
// that are replaced.
|
||||
const YIELD_INTERVAL = 100;
|
||||
let count = YIELD_INTERVAL;
|
||||
|
||||
for (let root of this.roots) {
|
||||
root.swapText(target);
|
||||
if (count-- == 0) {
|
||||
count = YIELD_INTERVAL;
|
||||
yield CommonUtils.laterTickResolvingPromise();
|
||||
}
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This class represents an item for translation. It's basically our
|
||||
* wrapper class around a node returned by getTranslationNode, with
|
||||
* more data and structural information on it.
|
||||
*
|
||||
* At the end of the translation process, besides the properties below,
|
||||
* a TranslationItem will contain two other properties: one called "original"
|
||||
* and one called "translation". They are twin objects, one which reflect
|
||||
* the structure of that node in its original state, and the other in its
|
||||
* translated state.
|
||||
*
|
||||
* The "original" array is generated in the generateTextForItem function,
|
||||
* and the "translation" array is generated when the translation results
|
||||
* are parsed.
|
||||
*
|
||||
* They are both arrays, which contain a mix of strings and references to
|
||||
* child TranslationItems. The references in both arrays point to the * same *
|
||||
* TranslationItem object, but they might appear in different orders between the
|
||||
* "original" and "translation" arrays.
|
||||
*
|
||||
* An example:
|
||||
*
|
||||
* English: <div id="n1">Welcome to <b id="n2">Mozilla's</b> website</div>
|
||||
* Portuguese: <div id="n1">Bem vindo a pagina <b id="n2">da Mozilla</b></div>
|
||||
*
|
||||
* TranslationItem n1 = {
|
||||
* id: 1,
|
||||
* original: ["Welcome to", ptr to n2, "website"]
|
||||
* translation: ["Bem vindo a pagina", ptr to n2]
|
||||
* }
|
||||
*
|
||||
* TranslationItem n2 = {
|
||||
* id: 2,
|
||||
* original: ["Mozilla's"],
|
||||
* translation: ["da Mozilla"]
|
||||
* }
|
||||
*/
|
||||
function TranslationItem(node, id, isRoot) {
|
||||
this.nodeRef = node;
|
||||
this.id = id;
|
||||
this.isRoot = isRoot;
|
||||
this.children = [];
|
||||
}
|
||||
|
||||
TranslationItem.prototype = {
|
||||
isRoot: false,
|
||||
isSimpleRoot: false,
|
||||
|
||||
toString: function() {
|
||||
let rootType = this._isRoot
|
||||
? (this._isSimpleRoot ? ' (simple root)' : ' (non simple root)')
|
||||
: '';
|
||||
return "[object TranslationItem: <" + this.nodeRef.localName + ">"
|
||||
+ rootType + "]";
|
||||
},
|
||||
|
||||
/**
|
||||
* This function will parse the result of the translation of one translation
|
||||
* item. If this item was a simple root, all we sent was a plain-text version
|
||||
* of it, so the result is also straightforward text.
|
||||
*
|
||||
* For non-simple roots, we sent a simplified HTML representation of that
|
||||
* node, and we'll first parse that into an HTML doc and then call the
|
||||
* parseResultNode helper function to parse it.
|
||||
*
|
||||
* While parsing, the result is stored in the "translation" field of the
|
||||
* TranslationItem, which will be used to display the final translation when
|
||||
* all items are finished. It remains stored too to allow back-and-forth
|
||||
* switching between the "Show Original" and "Show Translation" functions.
|
||||
*
|
||||
* @param result A string with the textual result received from the server,
|
||||
* which can be plain-text or a serialized HTML doc.
|
||||
*/
|
||||
parseResult: function(result) {
|
||||
if (this.isSimpleRoot) {
|
||||
this.translation = [result];
|
||||
return;
|
||||
}
|
||||
|
||||
let domParser = Cc["@mozilla.org/xmlextras/domparser;1"]
|
||||
.createInstance(Ci.nsIDOMParser);
|
||||
|
||||
let doc = domParser.parseFromString(result, "text/html");
|
||||
parseResultNode(this, doc.body.firstChild);
|
||||
},
|
||||
|
||||
/**
|
||||
* This function finds a child TranslationItem
|
||||
* with the given id.
|
||||
* @param id The id to look for, in the format "n#"
|
||||
* @returns A TranslationItem with the given id, or null if
|
||||
* it was not found.
|
||||
*/
|
||||
getChildById: function(id) {
|
||||
for (let child of this.children) {
|
||||
if (("n" + child.id) == id) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Swap the text of this TranslationItem between
|
||||
* its original and translated states.
|
||||
*
|
||||
* @param target A string that is either "translation"
|
||||
* or "original".
|
||||
*/
|
||||
swapText: function(target) {
|
||||
swapTextForItem(this, target);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function to parse a HTML doc result.
|
||||
* How it works:
|
||||
*
|
||||
* An example result string is:
|
||||
*
|
||||
* <div id="n1">Hello <b id="n2">World</b> of Mozilla.</div>
|
||||
*
|
||||
* For an element node, we look at its id and find the corresponding
|
||||
* TranslationItem that was associated with this node, and then we
|
||||
* walk down it repeating the process.
|
||||
*
|
||||
* For text nodes we simply add it as a string.
|
||||
*/
|
||||
function parseResultNode(item, node) {
|
||||
item.translation = [];
|
||||
for (let child of node.childNodes) {
|
||||
if (child.nodeType == TEXT_NODE) {
|
||||
item.translation.push(child.nodeValue);
|
||||
} else {
|
||||
let translationItemChild = item.getChildById(child.id);
|
||||
|
||||
if (translationItemChild) {
|
||||
item.translation.push(translationItemChild);
|
||||
parseResultNode(translationItemChild, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to swap the text of a TranslationItem
|
||||
* between its original and translated states.
|
||||
*
|
||||
* @param item A TranslationItem object
|
||||
* @param target A string that is either "translation"
|
||||
* or "original".
|
||||
*/
|
||||
function swapTextForItem(item, target) {
|
||||
// visitStack is the stack of items that we still need to visit.
|
||||
// Let's start the process by adding the root item.
|
||||
let visitStack = [ item ];
|
||||
let source = target == "translation" ? "original" : "translation";
|
||||
|
||||
while (visitStack.length > 0) {
|
||||
let curItem = visitStack.shift();
|
||||
|
||||
let domNode = curItem.nodeRef;
|
||||
if (!domNode) {
|
||||
// Skipping this item due to a missing node.
|
||||
continue;
|
||||
}
|
||||
|
||||
let sourceNodeCount = 0;
|
||||
|
||||
if (!curItem[target]) {
|
||||
// Translation not found for this item. This could be due to
|
||||
// an error in the server response. For example, if a translation
|
||||
// was broken in various chunks, and one of the chunks failed,
|
||||
// the items from that chunk will be missing its "translation"
|
||||
// field.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Now let's walk through all items in the `target` array of the
|
||||
// TranslationItem. This means either the TranslationItem.original or
|
||||
// TranslationItem.translation array.
|
||||
for (let child of curItem[target]) {
|
||||
// If the array element is another TranslationItem object, let's
|
||||
// add it to the stack to be visited
|
||||
if (child instanceof TranslationItem) {
|
||||
// Adding this child to the stack.
|
||||
visitStack.push(child);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If it's a string, say, the Nth string of the `target` array, let's
|
||||
// replace the Nth child TextNode of this element with this string.
|
||||
// During our translation process we skipped all empty text nodes, so we
|
||||
// must also skip them here. If there are not enough text nodes to be used,
|
||||
// a new text node will be created and appended to the end of the element.
|
||||
let targetTextNode = getNthNonEmptyTextNodeFromElement(sourceNodeCount++, domNode);
|
||||
|
||||
// A trailing and a leading space must be preserved because they are meaningful in HTML.
|
||||
let preSpace = targetTextNode.nodeValue.startsWith(" ") ? " " : "";
|
||||
let endSpace = targetTextNode.nodeValue.endsWith(" ") ? " " : "";
|
||||
targetTextNode.nodeValue = preSpace + child + endSpace;
|
||||
}
|
||||
|
||||
// The translated version of a node might have less text nodes than its original
|
||||
// version. If that's the case, let's clear the remaining nodes.
|
||||
if (sourceNodeCount > 0) {
|
||||
clearRemainingNonEmptyTextNodesFromElement(sourceNodeCount, domNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getNthNonEmptyTextNodeFromElement(n, element) {
|
||||
for (let childNode of element.childNodes) {
|
||||
if (childNode.nodeType == Ci.nsIDOMNode.TEXT_NODE &&
|
||||
childNode.nodeValue.trim() != "") {
|
||||
if (n-- == 0)
|
||||
return childNode;
|
||||
}
|
||||
}
|
||||
|
||||
// If there are not enough DOM nodes, let's create a new one.
|
||||
return element.appendChild(element.ownerDocument.createTextNode(""));
|
||||
}
|
||||
|
||||
function clearRemainingNonEmptyTextNodesFromElement(start, element) {
|
||||
let count = 0;
|
||||
for (let childNode of element.childNodes) {
|
||||
if (childNode.nodeType == Ci.nsIDOMNode.TEXT_NODE &&
|
||||
childNode.nodeValue.trim() != "") {
|
||||
if (count++ >= start) {
|
||||
childNode.nodeValue = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,10 +5,13 @@
|
|||
JS_MODULES_PATH = 'modules/translation'
|
||||
|
||||
EXTRA_JS_MODULES = [
|
||||
'BingTranslator.jsm',
|
||||
'cld2/cld-worker.js',
|
||||
'cld2/cld-worker.js.mem',
|
||||
'LanguageDetector.jsm',
|
||||
'Translation.jsm'
|
||||
'Translation.jsm',
|
||||
'TranslationContentHandler.jsm',
|
||||
'TranslationDocument.jsm'
|
||||
]
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
|
|
|
@ -53,6 +53,8 @@ browser.jar:
|
|||
content/browser/devtools/codemirror/comment-fold.js (sourceeditor/codemirror/fold/comment-fold.js)
|
||||
content/browser/devtools/codemirror/xml-fold.js (sourceeditor/codemirror/fold/xml-fold.js)
|
||||
content/browser/devtools/codemirror/foldgutter.js (sourceeditor/codemirror/fold/foldgutter.js)
|
||||
content/browser/devtools/codemirror/tern.js (sourceeditor/codemirror/tern.js)
|
||||
content/browser/devtools/codemirror/show-hint.js (sourceeditor/codemirror/show-hint.js)
|
||||
content/browser/devtools/codemirror/mozilla.css (sourceeditor/codemirror/mozilla.css)
|
||||
content/browser/devtools/debugger.xul (debugger/debugger.xul)
|
||||
content/browser/devtools/debugger.css (debugger/debugger.css)
|
||||
|
|
|
@ -35,6 +35,7 @@ const DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
|
|||
const PREF_RECENT_FILES_MAX = "devtools.scratchpad.recentFilesMax";
|
||||
const SHOW_TRAILING_SPACE = "devtools.scratchpad.showTrailingSpace";
|
||||
const ENABLE_CODE_FOLDING = "devtools.scratchpad.enableCodeFolding";
|
||||
const ENABLE_AUTOCOMPLETION = "devtools.scratchpad.enableAutocompletion";
|
||||
|
||||
const VARIABLES_VIEW_URL = "chrome://browser/content/devtools/widgets/VariablesView.xul";
|
||||
|
||||
|
@ -1605,15 +1606,17 @@ var Scratchpad = {
|
|||
mode: Editor.modes.js,
|
||||
value: initialText,
|
||||
lineNumbers: true,
|
||||
contextMenu: "scratchpad-text-popup",
|
||||
showTrailingSpace: Services.prefs.getBoolPref(SHOW_TRAILING_SPACE),
|
||||
enableCodeFolding: Services.prefs.getBoolPref(ENABLE_CODE_FOLDING),
|
||||
contextMenu: "scratchpad-text-popup"
|
||||
autocomplete: Services.prefs.getBoolPref(ENABLE_AUTOCOMPLETION),
|
||||
};
|
||||
|
||||
this.editor = new Editor(config);
|
||||
this.editor.appendTo(document.querySelector("#scratchpad-editor")).then(() => {
|
||||
var lines = initialText.split("\n");
|
||||
|
||||
this.editor.setupAutoCompletion();
|
||||
this.editor.on("change", this._onChanged);
|
||||
this.editor.on("save", () => this.saveFile());
|
||||
this.editor.focus();
|
||||
|
@ -1627,7 +1630,7 @@ var Scratchpad = {
|
|||
this.populateRecentFilesMenu();
|
||||
PreferenceObserver.init();
|
||||
CloseObserver.init();
|
||||
}).then(null, (err) => console.log(err.message));
|
||||
}).then(null, (err) => console.error(err));
|
||||
this._setupCommandListeners();
|
||||
this._setupPopupShowingListeners();
|
||||
},
|
||||
|
|
|
@ -3,6 +3,7 @@ skip-if = e10s # Bug ?????? - devtools tests disabled with e10s
|
|||
subsuite = devtools
|
||||
support-files = head.js
|
||||
|
||||
[browser_scratchpad_autocomplete.js]
|
||||
[browser_scratchpad_browser_last_window_closing.js]
|
||||
[browser_scratchpad_reset_undo.js]
|
||||
[browser_scratchpad_display_outputs_errors.js]
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* Bug 968896 */
|
||||
|
||||
// Test the completions using numbers.
|
||||
const source = "0x1.";
|
||||
const completions = ["toExponential", "toFixed", "toString"];
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
|
||||
function test() {
|
||||
const options = { tabContent: "test scratchpad autocomplete" };
|
||||
openTabAndScratchpad(options)
|
||||
.then(Task.async(runTests))
|
||||
.then(finish, console.error);
|
||||
}
|
||||
|
||||
|
||||
function* runTests([win, sp]) {
|
||||
const {editor} = sp;
|
||||
const editorWin = editor.container.contentWindow;
|
||||
|
||||
// Show the completions popup.
|
||||
sp.setText(source);
|
||||
sp.editor.setCursor({ line: 0, ch: source.length });
|
||||
yield keyOnce("suggestion-entered", " ", { ctrlKey: true });
|
||||
|
||||
// Get the hints popup container.
|
||||
const hints = editorWin.document.querySelector(".CodeMirror-hints");
|
||||
|
||||
ok(hints,
|
||||
"The hint container should exist.")
|
||||
is(hints.childNodes.length, 3,
|
||||
"The hint container should have the completions.");
|
||||
|
||||
let i = 0;
|
||||
for (let completion of completions) {
|
||||
let active = hints.querySelector(".CodeMirror-hint-active");
|
||||
is(active.textContent, completion,
|
||||
"Check that completion " + i++ + " is what is expected.");
|
||||
yield keyOnce("suggestion-entered", "VK_DOWN");
|
||||
}
|
||||
|
||||
// We should have looped around to the first suggestion again. Accept it.
|
||||
yield keyOnce("after-suggest", "VK_RETURN");
|
||||
|
||||
is(sp.getText(), source + completions[0],
|
||||
"Autocompletion should work and select the right element.");
|
||||
|
||||
// Check that the information tooltips work.
|
||||
sp.setText("5");
|
||||
yield keyOnce("show-information", " ", { shiftKey: true });
|
||||
|
||||
// Get the information container.
|
||||
const info = editorWin.document.querySelector(".CodeMirror-Tern-information");
|
||||
ok(info,
|
||||
"Info tooltip should appear.");
|
||||
is(info.textContent.slice(0, 6), "number",
|
||||
"Info tooltip should have expected contents.");
|
||||
|
||||
function keyOnce(event, key, opts = {}) {
|
||||
const p = editor.once(event);
|
||||
EventUtils.synthesizeKey(key, opts, editorWin);
|
||||
return p;
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@
|
|||
const {NetUtil} = Cu.import("resource://gre/modules/NetUtil.jsm", {});
|
||||
const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {});
|
||||
const {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
const {console} = Cu.import("resource://gre/modules/devtools/Console.jsm", {});
|
||||
const {require} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
|
||||
|
||||
let gScratchpadWindow; // Reference to the Scratchpad chrome window object
|
||||
|
||||
|
@ -36,10 +38,8 @@ SimpleTest.registerCleanupFunction(() => {
|
|||
* gScratchpadWindow global is also updated to reference the new window
|
||||
* object.
|
||||
*/
|
||||
function openScratchpad(aReadyCallback, aOptions)
|
||||
function openScratchpad(aReadyCallback, aOptions = {})
|
||||
{
|
||||
aOptions = aOptions || {};
|
||||
|
||||
let win = aOptions.window ||
|
||||
Scratchpad.ScratchpadManager.openScratchpad(aOptions.state);
|
||||
if (!win) {
|
||||
|
@ -70,6 +70,30 @@ function openScratchpad(aReadyCallback, aOptions)
|
|||
return gScratchpadWindow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a new tab and then open a scratchpad.
|
||||
* @param object aOptions
|
||||
* Optional. Options for opening the tab and scratchpad. In addition
|
||||
* to the options supported by openScratchpad, the following options
|
||||
* are supported:
|
||||
* - tabContent
|
||||
* A string providing the html content of the tab.
|
||||
* @return Promise
|
||||
*/
|
||||
function openTabAndScratchpad(aOptions = {})
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
return new promise(resolve => {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
let {selectedBrowser} = gBrowser;
|
||||
selectedBrowser.addEventListener("load", function onLoad() {
|
||||
selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
openScratchpad((win, sp) => resolve([win, sp]), aOptions);
|
||||
}, true);
|
||||
content.location = "data:text/html;charset=utf8," + (aOptions.tabContent || "");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a temporary file, write to it and call a callback
|
||||
* when done.
|
||||
|
@ -180,7 +204,6 @@ function runAsyncCallbackTests(aScratchpad, aTests)
|
|||
return deferred.promise;
|
||||
}
|
||||
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
if (gScratchpadWindow) {
|
||||
|
|
|
@ -6,20 +6,62 @@
|
|||
const cssAutoCompleter = require("devtools/sourceeditor/css-autocompleter");
|
||||
const { AutocompletePopup } = require("devtools/shared/autocomplete-popup");
|
||||
|
||||
const CM_TERN_SCRIPTS = [
|
||||
"chrome://browser/content/devtools/codemirror/tern.js",
|
||||
"chrome://browser/content/devtools/codemirror/show-hint.js"
|
||||
];
|
||||
|
||||
const privates = new WeakMap();
|
||||
|
||||
/**
|
||||
* Prepares an editor instance for autocompletion, setting up the popup and the
|
||||
* CSS completer instance.
|
||||
* Prepares an editor instance for autocompletion.
|
||||
*/
|
||||
function setupAutoCompletion(ctx, walker) {
|
||||
function setupAutoCompletion(ctx, options) {
|
||||
let { cm, ed, Editor } = ctx;
|
||||
|
||||
let win = ed.container.contentWindow.wrappedJSObject;
|
||||
let {CodeMirror} = win;
|
||||
|
||||
let completer = null;
|
||||
if (ed.config.mode == Editor.modes.css)
|
||||
completer = new cssAutoCompleter({walker: walker});
|
||||
let autocompleteKey = "Ctrl-" +
|
||||
Editor.keyFor("autocompletion", { noaccel: true });
|
||||
if (ed.config.mode == Editor.modes.js) {
|
||||
let defs = [
|
||||
"tern/browser",
|
||||
"tern/ecma5",
|
||||
].map(require);
|
||||
|
||||
CM_TERN_SCRIPTS.forEach(ed.loadScript, ed);
|
||||
win.tern = require("tern/tern");
|
||||
cm.tern = new CodeMirror.TernServer({ defs: defs });
|
||||
cm.on("cursorActivity", (cm) => {
|
||||
cm.tern.updateArgHints(cm);
|
||||
});
|
||||
|
||||
let keyMap = {};
|
||||
|
||||
keyMap[autocompleteKey] = (cm) => {
|
||||
cm.tern.getHint(cm, (data) => {
|
||||
CodeMirror.on(data, "shown", () => ed.emit("before-suggest"));
|
||||
CodeMirror.on(data, "close", () => ed.emit("after-suggest"));
|
||||
CodeMirror.on(data, "select", () => ed.emit("suggestion-entered"));
|
||||
CodeMirror.showHint(cm, (cm, cb) => cb(data), { async: true });
|
||||
});
|
||||
};
|
||||
|
||||
keyMap[Editor.keyFor("showInformation", { noaccel: true })] = (cm) => {
|
||||
cm.tern.showType(cm, null, () => {
|
||||
ed.emit("show-information");
|
||||
});
|
||||
};
|
||||
|
||||
cm.addKeyMap(keyMap);
|
||||
|
||||
// TODO: Integrate tern autocompletion with this autocomplete API.
|
||||
return;
|
||||
} else if (ed.config.mode == Editor.modes.css) {
|
||||
completer = new cssAutoCompleter({walker: options.walker});
|
||||
}
|
||||
|
||||
let popup = new AutocompletePopup(win.parent.document, {
|
||||
position: "after_start",
|
||||
|
@ -34,14 +76,14 @@ function setupAutoCompletion(ctx, walker) {
|
|||
return;
|
||||
}
|
||||
|
||||
return win.CodeMirror.Pass;
|
||||
return CodeMirror.Pass;
|
||||
};
|
||||
|
||||
let keyMap = {
|
||||
"Tab": cycle,
|
||||
"Down": cycle,
|
||||
"Shift-Tab": cycle.bind(this, true),
|
||||
"Up": cycle.bind(this, true),
|
||||
"Shift-Tab": cycle.bind(null, true),
|
||||
"Up": cycle.bind(null, true),
|
||||
"Enter": () => {
|
||||
if (popup && popup.isOpen) {
|
||||
if (!privates.get(ed).suggestionInsertedOnce) {
|
||||
|
@ -56,10 +98,10 @@ function setupAutoCompletion(ctx, walker) {
|
|||
return;
|
||||
}
|
||||
|
||||
return win.CodeMirror.Pass;
|
||||
return CodeMirror.Pass;
|
||||
}
|
||||
};
|
||||
keyMap[Editor.accel("Space")] = cm => autoComplete(ctx);
|
||||
keyMap[autocompleteKey] = cm => autoComplete(ctx);
|
||||
cm.addKeyMap(keyMap);
|
||||
|
||||
cm.on("keydown", (cm, e) => onEditorKeypress(ctx, e));
|
||||
|
|
|
@ -134,4 +134,101 @@ selector in floating-scrollbar-light.css across all platforms. */
|
|||
.CodeMirror-foldgutter-folded:after {
|
||||
font-size: 120%;
|
||||
content: "\25B8";
|
||||
}
|
||||
}
|
||||
|
||||
.CodeMirror-hints {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
overflow: hidden;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 2px;
|
||||
border-radius: 3px;
|
||||
font-size: 90%;
|
||||
max-height: 20em;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.CodeMirror-hint {
|
||||
margin: 0;
|
||||
padding: 0 4px;
|
||||
border-radius: 2px;
|
||||
max-width: 19em;
|
||||
overflow: hidden;
|
||||
white-space: pre;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion {
|
||||
-moz-padding-start: 22px;
|
||||
position: relative;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion:before {
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
bottom: 2px;
|
||||
border-radius: 50%;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-unknown:before {
|
||||
content: "?";
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-object:before {
|
||||
content: "O";
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-fn:before {
|
||||
content: "F";
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-array:before {
|
||||
content: "A";
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-number:before {
|
||||
content: "N";
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-string:before {
|
||||
content: "S";
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-bool:before {
|
||||
content: "B";
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-guess {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-tooltip {
|
||||
border-radius: 3px;
|
||||
padding: 2px 5px;
|
||||
white-space: pre-wrap;
|
||||
max-width: 40em;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-hint-doc {
|
||||
max-width: 25em;
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-farg-current {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-fhint-guess {
|
||||
opacity: .7;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,341 @@
|
|||
(function() {
|
||||
"use strict";
|
||||
|
||||
var HINT_ELEMENT_CLASS = "CodeMirror-hint";
|
||||
var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
|
||||
|
||||
CodeMirror.showHint = function(cm, getHints, options) {
|
||||
// We want a single cursor position.
|
||||
if (cm.somethingSelected()) return;
|
||||
if (getHints == null) {
|
||||
if (options && options.async) return;
|
||||
else getHints = CodeMirror.hint.auto;
|
||||
}
|
||||
|
||||
if (cm.state.completionActive) cm.state.completionActive.close();
|
||||
|
||||
var completion = cm.state.completionActive = new Completion(cm, getHints, options || {});
|
||||
CodeMirror.signal(cm, "startCompletion", cm);
|
||||
if (completion.options.async)
|
||||
getHints(cm, function(hints) { completion.showHints(hints); }, completion.options);
|
||||
else
|
||||
return completion.showHints(getHints(cm, completion.options));
|
||||
};
|
||||
|
||||
function Completion(cm, getHints, options) {
|
||||
this.cm = cm;
|
||||
this.getHints = getHints;
|
||||
this.options = options;
|
||||
this.widget = this.onClose = null;
|
||||
}
|
||||
|
||||
Completion.prototype = {
|
||||
close: function() {
|
||||
if (!this.active()) return;
|
||||
this.cm.state.completionActive = null;
|
||||
|
||||
if (this.widget) this.widget.close();
|
||||
if (this.onClose) this.onClose();
|
||||
CodeMirror.signal(this.cm, "endCompletion", this.cm);
|
||||
},
|
||||
|
||||
active: function() {
|
||||
return this.cm.state.completionActive == this;
|
||||
},
|
||||
|
||||
pick: function(data, i) {
|
||||
var completion = data.list[i];
|
||||
if (completion.hint) completion.hint(this.cm, data, completion);
|
||||
else this.cm.replaceRange(getText(completion), data.from, data.to);
|
||||
CodeMirror.signal(data, "pick", completion);
|
||||
this.close();
|
||||
},
|
||||
|
||||
showHints: function(data) {
|
||||
if (!data || !data.list.length || !this.active()) return this.close();
|
||||
|
||||
if (this.options.completeSingle != false && data.list.length == 1)
|
||||
this.pick(data, 0);
|
||||
else
|
||||
this.showWidget(data);
|
||||
},
|
||||
|
||||
showWidget: function(data) {
|
||||
this.widget = new Widget(this, data);
|
||||
CodeMirror.signal(data, "shown");
|
||||
|
||||
var debounce = 0, completion = this, finished;
|
||||
var closeOn = this.options.closeCharacters || /[\s()\[\]{};:>,]/;
|
||||
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");
|
||||
}
|
||||
|
||||
function update() {
|
||||
if (finished) return;
|
||||
CodeMirror.signal(data, "update");
|
||||
if (completion.options.async)
|
||||
completion.getHints(completion.cm, finishUpdate, completion.options);
|
||||
else
|
||||
finishUpdate(completion.getHints(completion.cm, completion.options));
|
||||
}
|
||||
function finishUpdate(data_) {
|
||||
data = data_;
|
||||
if (finished) return;
|
||||
if (!data || !data.list.length) return done();
|
||||
completion.widget = new Widget(completion, 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();
|
||||
} else {
|
||||
debounce = requestAnimationFrame(update);
|
||||
if (completion.widget) completion.widget.close();
|
||||
}
|
||||
}
|
||||
this.cm.on("cursorActivity", activity);
|
||||
this.onClose = done;
|
||||
}
|
||||
};
|
||||
|
||||
function getText(completion) {
|
||||
if (typeof completion == "string") return completion;
|
||||
else return completion.text;
|
||||
}
|
||||
|
||||
function buildKeyMap(options, handle) {
|
||||
var baseMap = {
|
||||
Up: function() {handle.moveFocus(-1);},
|
||||
Down: function() {handle.moveFocus(1);},
|
||||
PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
|
||||
PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
|
||||
Home: function() {handle.setFocus(0);},
|
||||
End: function() {handle.setFocus(handle.length - 1);},
|
||||
Enter: handle.pick,
|
||||
Tab: handle.pick,
|
||||
Esc: handle.close
|
||||
};
|
||||
var ourMap = options.customKeys ? {} : baseMap;
|
||||
function addBinding(key, val) {
|
||||
var bound;
|
||||
if (typeof val != "string")
|
||||
bound = function(cm) { return val(cm, handle); };
|
||||
// This mechanism is deprecated
|
||||
else if (baseMap.hasOwnProperty(val))
|
||||
bound = baseMap[val];
|
||||
else
|
||||
bound = val;
|
||||
ourMap[key] = bound;
|
||||
}
|
||||
if (options.customKeys)
|
||||
for (var key in options.customKeys) if (options.customKeys.hasOwnProperty(key))
|
||||
addBinding(key, options.customKeys[key]);
|
||||
if (options.extraKeys)
|
||||
for (var key in options.extraKeys) if (options.extraKeys.hasOwnProperty(key))
|
||||
addBinding(key, options.extraKeys[key]);
|
||||
return ourMap;
|
||||
}
|
||||
|
||||
function getHintElement(hintsElement, el) {
|
||||
while (el && el != hintsElement) {
|
||||
if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
|
||||
el = el.parentNode;
|
||||
}
|
||||
}
|
||||
|
||||
function Widget(completion, data) {
|
||||
this.completion = completion;
|
||||
this.data = data;
|
||||
var widget = this, cm = completion.cm, options = completion.options;
|
||||
|
||||
var hints = this.hints = document.createElement("ul");
|
||||
hints.className = "CodeMirror-hints";
|
||||
this.selectedHint = options.getDefaultSelection ? options.getDefaultSelection(cm,options,data) : 0;
|
||||
|
||||
var completions = data.list;
|
||||
for (var i = 0; i < completions.length; ++i) {
|
||||
var elt = hints.appendChild(document.createElement("li")), cur = completions[i];
|
||||
var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
|
||||
if (cur.className != null) className = cur.className + " " + className;
|
||||
elt.className = className;
|
||||
if (cur.render) cur.render(elt, data, cur);
|
||||
else elt.appendChild(document.createTextNode(cur.displayText || getText(cur)));
|
||||
elt.hintId = i;
|
||||
}
|
||||
|
||||
var pos = cm.cursorCoords(options.alignWithWord !== false ? data.from : null);
|
||||
var left = pos.left, top = pos.bottom, below = true;
|
||||
hints.style.left = left + "px";
|
||||
hints.style.top = top + "px";
|
||||
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
|
||||
var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
|
||||
var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
|
||||
(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);
|
||||
if (curTop - height > 0) { // Fits above cursor
|
||||
hints.style.top = (top = curTop - height) + "px";
|
||||
below = false;
|
||||
} else if (height > winH) {
|
||||
hints.style.height = (winH - 5) + "px";
|
||||
hints.style.top = (top = pos.bottom - box.top) + "px";
|
||||
var cursor = cm.getCursor();
|
||||
if (data.from.ch != cursor.ch) {
|
||||
pos = cm.cursorCoords(cursor);
|
||||
hints.style.left = (left = pos.left) + "px";
|
||||
box = hints.getBoundingClientRect();
|
||||
}
|
||||
}
|
||||
}
|
||||
var overlapX = box.left - winW;
|
||||
if (overlapX > 0) {
|
||||
if (box.right - box.left > winW) {
|
||||
hints.style.width = (winW - 5) + "px";
|
||||
overlapX -= (box.right - box.left) - winW;
|
||||
}
|
||||
hints.style.left = (left = pos.left - overlapX) + "px";
|
||||
}
|
||||
|
||||
cm.addKeyMap(this.keyMap = buildKeyMap(options, {
|
||||
moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
|
||||
setFocus: function(n) { widget.changeActive(n); },
|
||||
menuSize: function() { return widget.screenAmount(); },
|
||||
length: completions.length,
|
||||
close: function() { completion.close(); },
|
||||
pick: function() { widget.pick(); },
|
||||
data: data
|
||||
}));
|
||||
|
||||
if (options.closeOnUnfocus !== false) {
|
||||
var closingOnBlur;
|
||||
cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
|
||||
cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
|
||||
}
|
||||
|
||||
var startScroll = cm.getScrollInfo();
|
||||
cm.on("scroll", this.onScroll = function() {
|
||||
var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
|
||||
var newTop = top + startScroll.top - curScroll.top;
|
||||
var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop);
|
||||
if (!below) point += hints.offsetHeight;
|
||||
if (point <= editor.top || point >= editor.bottom) return completion.close();
|
||||
hints.style.top = newTop + "px";
|
||||
hints.style.left = (left + startScroll.left - curScroll.left) + "px";
|
||||
});
|
||||
|
||||
CodeMirror.on(hints, "dblclick", function(e) {
|
||||
var t = getHintElement(hints, e.target || e.srcElement);
|
||||
if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
|
||||
});
|
||||
|
||||
CodeMirror.on(hints, "click", function(e) {
|
||||
var t = getHintElement(hints, e.target || e.srcElement);
|
||||
if (t && t.hintId != null) {
|
||||
widget.changeActive(t.hintId);
|
||||
if (options.completeOnSingleClick) widget.pick();
|
||||
}
|
||||
});
|
||||
|
||||
CodeMirror.on(hints, "mousedown", function() {
|
||||
setTimeout(function(){cm.focus();}, 20);
|
||||
});
|
||||
|
||||
CodeMirror.signal(data, "select", completions[0], hints.firstChild);
|
||||
return true;
|
||||
}
|
||||
|
||||
Widget.prototype = {
|
||||
close: function() {
|
||||
if (this.completion.widget != this) return;
|
||||
this.completion.widget = null;
|
||||
this.hints.parentNode.removeChild(this.hints);
|
||||
this.completion.cm.removeKeyMap(this.keyMap);
|
||||
|
||||
var cm = this.completion.cm;
|
||||
if (this.completion.options.closeOnUnfocus !== false) {
|
||||
cm.off("blur", this.onBlur);
|
||||
cm.off("focus", this.onFocus);
|
||||
}
|
||||
cm.off("scroll", this.onScroll);
|
||||
},
|
||||
|
||||
pick: function() {
|
||||
this.completion.pick(this.data, this.selectedHint);
|
||||
},
|
||||
|
||||
changeActive: function(i, avoidWrap) {
|
||||
if (i >= this.data.list.length)
|
||||
i = avoidWrap ? this.data.list.length - 1 : 0;
|
||||
else if (i < 0)
|
||||
i = avoidWrap ? 0 : this.data.list.length - 1;
|
||||
if (this.selectedHint == i) return;
|
||||
var node = this.hints.childNodes[this.selectedHint];
|
||||
node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
|
||||
node = this.hints.childNodes[this.selectedHint = i];
|
||||
node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
|
||||
if (node.offsetTop < this.hints.scrollTop)
|
||||
this.hints.scrollTop = node.offsetTop - 3;
|
||||
else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
|
||||
this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
|
||||
CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
|
||||
},
|
||||
|
||||
screenAmount: function() {
|
||||
return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
|
||||
}
|
||||
};
|
||||
|
||||
CodeMirror.registerHelper("hint", "auto", function(cm, options) {
|
||||
var helpers = cm.getHelpers(cm.getCursor(), "hint");
|
||||
if (helpers.length) {
|
||||
for (var i = 0; i < helpers.length; i++) {
|
||||
var cur = helpers[i](cm, options);
|
||||
if (cur && cur.list.length) return cur;
|
||||
}
|
||||
} else {
|
||||
var words = cm.getHelper(cm.getCursor(), "hintWords");
|
||||
if (words) return CodeMirror.hint.fromList(cm, {words: words});
|
||||
}
|
||||
});
|
||||
|
||||
CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
|
||||
var cur = cm.getCursor(), token = cm.getTokenAt(cur);
|
||||
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)
|
||||
found.push(word);
|
||||
}
|
||||
|
||||
if (found.length) return {
|
||||
list: found,
|
||||
from: CodeMirror.Pos(cur.line, token.start),
|
||||
to: CodeMirror.Pos(cur.line, token.end)
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.commands.autocomplete = CodeMirror.showHint;
|
||||
})();
|
|
@ -0,0 +1,633 @@
|
|||
// Glue code between CodeMirror and Tern.
|
||||
//
|
||||
// Create a CodeMirror.TernServer to wrap an actual Tern server,
|
||||
// register open documents (CodeMirror.Doc instances) with it, and
|
||||
// call its methods to activate the assisting functions that Tern
|
||||
// provides.
|
||||
//
|
||||
// Options supported (all optional):
|
||||
// * defs: An array of JSON definition data structures.
|
||||
// * plugins: An object mapping plugin names to configuration
|
||||
// options.
|
||||
// * getFile: A function(name, c) that can be used to access files in
|
||||
// the project that haven't been loaded yet. Simply do c(null) to
|
||||
// indicate that a file is not available.
|
||||
// * fileFilter: A function(value, docName, doc) that will be applied
|
||||
// to documents before passing them on to Tern.
|
||||
// * switchToDoc: A function(name) that should, when providing a
|
||||
// multi-file view, switch the view or focus to the named file.
|
||||
// * showError: A function(editor, message) that can be used to
|
||||
// override the way errors are displayed.
|
||||
// * completionTip: Customize the content in tooltips for completions.
|
||||
// Is passed a single argument—the completion's data as returned by
|
||||
// Tern—and may return a string, DOM node, or null to indicate that
|
||||
// no tip should be shown. By default the docstring is shown.
|
||||
// * typeTip: Like completionTip, but for the tooltips shown for type
|
||||
// queries.
|
||||
// * responseFilter: A function(doc, query, request, error, data) that
|
||||
// will be applied to the Tern responses before treating them
|
||||
//
|
||||
//
|
||||
// It is possible to run the Tern server in a web worker by specifying
|
||||
// these additional options:
|
||||
// * useWorker: Set to true to enable web worker mode. You'll probably
|
||||
// want to feature detect the actual value you use here, for example
|
||||
// !!window.Worker.
|
||||
// * workerScript: The main script of the worker. Point this to
|
||||
// wherever you are hosting worker.js from this directory.
|
||||
// * workerDeps: An array of paths pointing (relative to workerScript)
|
||||
// to the Acorn and Tern libraries and any Tern plugins you want to
|
||||
// load. Or, if you minified those into a single script and included
|
||||
// them in the workerScript, simply leave this undefined.
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
// declare global: tern
|
||||
|
||||
CodeMirror.TernServer = function(options) {
|
||||
var self = this;
|
||||
this.options = options || {};
|
||||
var plugins = this.options.plugins || (this.options.plugins = {});
|
||||
if (!plugins.doc_comment) plugins.doc_comment = true;
|
||||
if (this.options.useWorker) {
|
||||
this.server = new WorkerServer(this);
|
||||
} else {
|
||||
this.server = new tern.Server({
|
||||
getFile: function(name, c) { return getFile(self, name, c); },
|
||||
async: true,
|
||||
defs: this.options.defs || [],
|
||||
plugins: plugins
|
||||
});
|
||||
}
|
||||
this.docs = Object.create(null);
|
||||
this.trackChange = function(doc, change) { trackChange(self, doc, change); };
|
||||
|
||||
this.cachedArgHints = null;
|
||||
this.activeArgHints = null;
|
||||
this.jumpStack = [];
|
||||
};
|
||||
|
||||
CodeMirror.TernServer.prototype = {
|
||||
addDoc: function(name, doc) {
|
||||
var data = {doc: doc, name: name, changed: null};
|
||||
this.server.addFile(name, docValue(this, data));
|
||||
CodeMirror.on(doc, "change", this.trackChange);
|
||||
return this.docs[name] = data;
|
||||
},
|
||||
|
||||
delDoc: function(name) {
|
||||
var found = this.docs[name];
|
||||
if (!found) return;
|
||||
CodeMirror.off(found.doc, "change", this.trackChange);
|
||||
delete this.docs[name];
|
||||
this.server.delFile(name);
|
||||
},
|
||||
|
||||
hideDoc: function(name) {
|
||||
closeArgHints(this);
|
||||
var found = this.docs[name];
|
||||
if (found && found.changed) sendDoc(this, found);
|
||||
},
|
||||
|
||||
complete: function(cm) {
|
||||
var self = this;
|
||||
CodeMirror.showHint(cm, function(cm, c) { return hint(self, cm, c); }, {async: true});
|
||||
},
|
||||
|
||||
getHint: function(cm, c) { return hint(this, cm, c); },
|
||||
|
||||
showType: function(cm, pos, c) { showType(this, cm, pos, c); },
|
||||
|
||||
updateArgHints: function(cm) { updateArgHints(this, cm); },
|
||||
|
||||
jumpToDef: function(cm) { jumpToDef(this, cm); },
|
||||
|
||||
jumpBack: function(cm) { jumpBack(this, cm); },
|
||||
|
||||
rename: function(cm) { rename(this, cm); },
|
||||
|
||||
request: function (cm, query, c, pos) {
|
||||
var self = this;
|
||||
var doc = findDoc(this, cm.getDoc());
|
||||
var request = buildRequest(this, doc, query, pos);
|
||||
|
||||
this.server.request(request, function (error, data) {
|
||||
if (!error && self.options.responseFilter)
|
||||
data = self.options.responseFilter(doc, query, request, error, data);
|
||||
c(error, data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var Pos = CodeMirror.Pos;
|
||||
var cls = "CodeMirror-Tern-";
|
||||
var bigDoc = 250;
|
||||
|
||||
function getFile(ts, name, c) {
|
||||
var buf = ts.docs[name];
|
||||
if (buf)
|
||||
c(docValue(ts, buf));
|
||||
else if (ts.options.getFile)
|
||||
ts.options.getFile(name, c);
|
||||
else
|
||||
c(null);
|
||||
}
|
||||
|
||||
function findDoc(ts, doc, name) {
|
||||
for (var n in ts.docs) {
|
||||
var cur = ts.docs[n];
|
||||
if (cur.doc == doc) return cur;
|
||||
}
|
||||
if (!name) for (var i = 0;; ++i) {
|
||||
n = "[doc" + (i || "") + "]";
|
||||
if (!ts.docs[n]) { name = n; break; }
|
||||
}
|
||||
return ts.addDoc(name, doc);
|
||||
}
|
||||
|
||||
function trackChange(ts, doc, change) {
|
||||
var data = findDoc(ts, doc);
|
||||
|
||||
var argHints = ts.cachedArgHints;
|
||||
if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) <= 0)
|
||||
ts.cachedArgHints = null;
|
||||
|
||||
var changed = data.changed;
|
||||
if (changed == null)
|
||||
data.changed = changed = {from: change.from.line, to: change.from.line};
|
||||
var end = change.from.line + (change.text.length - 1);
|
||||
if (change.from.line < changed.to) changed.to = changed.to - (change.to.line - end);
|
||||
if (end >= changed.to) changed.to = end + 1;
|
||||
if (changed.from > change.from.line) changed.from = change.from.line;
|
||||
|
||||
if (doc.lineCount() > bigDoc && change.to - changed.from > 100) setTimeout(function() {
|
||||
if (data.changed && data.changed.to - data.changed.from > 100) sendDoc(ts, data);
|
||||
}, 200);
|
||||
}
|
||||
|
||||
function sendDoc(ts, doc) {
|
||||
ts.server.request({files: [{type: "full", name: doc.name, text: docValue(ts, doc)}]}, function(error) {
|
||||
if (error) console.error(error);
|
||||
else doc.changed = null;
|
||||
});
|
||||
}
|
||||
|
||||
// Completion
|
||||
|
||||
function hint(ts, cm, c) {
|
||||
ts.request(cm, {type: "completions", types: true, docs: true, urls: true}, function(error, data) {
|
||||
if (error) return showError(ts, cm, error);
|
||||
var completions = [], after = "";
|
||||
var from = data.start, to = data.end;
|
||||
if (cm.getRange(Pos(from.line, from.ch - 2), from) == "[\"" &&
|
||||
cm.getRange(to, Pos(to.line, to.ch + 2)) != "\"]")
|
||||
after = "\"]";
|
||||
|
||||
for (var i = 0; i < data.completions.length; ++i) {
|
||||
var completion = data.completions[i], className = typeToIcon(completion.type);
|
||||
if (data.guess) className += " " + cls + "guess";
|
||||
completions.push({text: completion.name + after,
|
||||
displayText: completion.name,
|
||||
className: className,
|
||||
data: completion});
|
||||
}
|
||||
|
||||
var obj = {from: from, to: to, list: completions};
|
||||
var tooltip = null;
|
||||
CodeMirror.on(obj, "close", function() { remove(tooltip); });
|
||||
CodeMirror.on(obj, "update", function() { remove(tooltip); });
|
||||
CodeMirror.on(obj, "select", function(cur, node) {
|
||||
remove(tooltip);
|
||||
var content = ts.options.completionTip ? ts.options.completionTip(cur.data) : cur.data.doc;
|
||||
if (content) {
|
||||
tooltip = makeTooltip(node.parentNode.getBoundingClientRect().right + window.pageXOffset,
|
||||
node.getBoundingClientRect().top + window.pageYOffset, content);
|
||||
tooltip.className += " " + cls + "hint-doc";
|
||||
}
|
||||
});
|
||||
c(obj);
|
||||
});
|
||||
}
|
||||
|
||||
function typeToIcon(type) {
|
||||
var suffix;
|
||||
if (type == "?") suffix = "unknown";
|
||||
else if (type == "number" || type == "string" || type == "bool") suffix = type;
|
||||
else if (/^fn\(/.test(type)) suffix = "fn";
|
||||
else if (/^\[/.test(type)) suffix = "array";
|
||||
else suffix = "object";
|
||||
return cls + "completion " + cls + "completion-" + suffix;
|
||||
}
|
||||
|
||||
// Type queries
|
||||
|
||||
function showType(ts, cm, pos, c) {
|
||||
ts.request(cm, "type", function(error, data) {
|
||||
if (error) return showError(ts, cm, error);
|
||||
if (ts.options.typeTip) {
|
||||
var tip = ts.options.typeTip(data);
|
||||
} else {
|
||||
var tip = elt("span", cls + "information", elt("strong", null, data.type || "not found"));
|
||||
if (data.doc)
|
||||
tip.appendChild(document.createTextNode(" — " + data.doc));
|
||||
if (data.url) {
|
||||
tip.appendChild(document.createTextNode(" "));
|
||||
tip.appendChild(elt("a", null, "[docs]")).href = data.url;
|
||||
}
|
||||
}
|
||||
tempTooltip(cm, tip);
|
||||
c && c(tip);
|
||||
}, pos);
|
||||
}
|
||||
|
||||
// Maintaining argument hints
|
||||
|
||||
function updateArgHints(ts, cm) {
|
||||
closeArgHints(ts);
|
||||
|
||||
if (cm.somethingSelected()) return;
|
||||
var state = cm.getTokenAt(cm.getCursor()).state;
|
||||
var inner = CodeMirror.innerMode(cm.getMode(), state);
|
||||
if (inner.mode.name != "javascript") return;
|
||||
var lex = inner.state.lexical;
|
||||
if (lex.info != "call") return;
|
||||
|
||||
var ch, argPos = lex.pos || 0, tabSize = cm.getOption("tabSize");
|
||||
for (var line = cm.getCursor().line, e = Math.max(0, line - 9), found = false; line >= e; --line) {
|
||||
var str = cm.getLine(line), extra = 0;
|
||||
for (var pos = 0;;) {
|
||||
var tab = str.indexOf("\t", pos);
|
||||
if (tab == -1) break;
|
||||
extra += tabSize - (tab + extra) % tabSize - 1;
|
||||
pos = tab + 1;
|
||||
}
|
||||
ch = lex.column - extra;
|
||||
if (str.charAt(ch) == "(") {found = true; break;}
|
||||
}
|
||||
if (!found) return;
|
||||
|
||||
var start = Pos(line, ch);
|
||||
var cache = ts.cachedArgHints;
|
||||
if (cache && cache.doc == cm.getDoc() && cmpPos(start, cache.start) == 0)
|
||||
return showArgHints(ts, cm, argPos);
|
||||
|
||||
ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) {
|
||||
if (error || !data.type || !(/^fn\(/).test(data.type)) return;
|
||||
ts.cachedArgHints = {
|
||||
start: pos,
|
||||
type: parseFnType(data.type),
|
||||
name: data.exprName || data.name || "fn",
|
||||
guess: data.guess,
|
||||
doc: cm.getDoc()
|
||||
};
|
||||
showArgHints(ts, cm, argPos);
|
||||
});
|
||||
}
|
||||
|
||||
function showArgHints(ts, cm, pos) {
|
||||
closeArgHints(ts);
|
||||
|
||||
var cache = ts.cachedArgHints, tp = cache.type;
|
||||
var tip = elt("span", cache.guess ? cls + "fhint-guess" : null,
|
||||
elt("span", cls + "fname", cache.name), "(");
|
||||
for (var i = 0; i < tp.args.length; ++i) {
|
||||
if (i) tip.appendChild(document.createTextNode(", "));
|
||||
var arg = tp.args[i];
|
||||
tip.appendChild(elt("span", cls + "farg" + (i == pos ? " " + cls + "farg-current" : ""), arg.name || "?"));
|
||||
if (arg.type != "?") {
|
||||
tip.appendChild(document.createTextNode(":\u00a0"));
|
||||
tip.appendChild(elt("span", cls + "type", arg.type));
|
||||
}
|
||||
}
|
||||
tip.appendChild(document.createTextNode(tp.rettype ? ") ->\u00a0" : ")"));
|
||||
if (tp.rettype) tip.appendChild(elt("span", cls + "type", tp.rettype));
|
||||
var place = cm.cursorCoords(null, "page");
|
||||
ts.activeArgHints = makeTooltip(place.right + 1, place.bottom, tip);
|
||||
}
|
||||
|
||||
function parseFnType(text) {
|
||||
var args = [], pos = 3;
|
||||
|
||||
function skipMatching(upto) {
|
||||
var depth = 0, start = pos;
|
||||
for (;;) {
|
||||
var next = text.charAt(pos);
|
||||
if (upto.test(next) && !depth) return text.slice(start, pos);
|
||||
if (/[{\[\(]/.test(next)) ++depth;
|
||||
else if (/[}\]\)]/.test(next)) --depth;
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse arguments
|
||||
if (text.charAt(pos) != ")") for (;;) {
|
||||
var name = text.slice(pos).match(/^([^, \(\[\{]+): /);
|
||||
if (name) {
|
||||
pos += name[0].length;
|
||||
name = name[1];
|
||||
}
|
||||
args.push({name: name, type: skipMatching(/[\),]/)});
|
||||
if (text.charAt(pos) == ")") break;
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
var rettype = text.slice(pos).match(/^\) -> (.*)$/);
|
||||
|
||||
return {args: args, rettype: rettype && rettype[1]};
|
||||
}
|
||||
|
||||
// Moving to the definition of something
|
||||
|
||||
function jumpToDef(ts, cm) {
|
||||
function inner(varName) {
|
||||
var req = {type: "definition", variable: varName || null};
|
||||
var doc = findDoc(ts, cm.getDoc());
|
||||
ts.server.request(buildRequest(ts, doc, req), function(error, data) {
|
||||
if (error) return showError(ts, cm, error);
|
||||
if (!data.file && data.url) { window.open(data.url); return; }
|
||||
|
||||
if (data.file) {
|
||||
var localDoc = ts.docs[data.file], found;
|
||||
if (localDoc && (found = findContext(localDoc.doc, data))) {
|
||||
ts.jumpStack.push({file: doc.name,
|
||||
start: cm.getCursor("from"),
|
||||
end: cm.getCursor("to")});
|
||||
moveTo(ts, doc, localDoc, found.start, found.end);
|
||||
return;
|
||||
}
|
||||
}
|
||||
showError(ts, cm, "Could not find a definition.");
|
||||
});
|
||||
}
|
||||
|
||||
if (!atInterestingExpression(cm))
|
||||
dialog(cm, "Jump to variable", function(name) { if (name) inner(name); });
|
||||
else
|
||||
inner();
|
||||
}
|
||||
|
||||
function jumpBack(ts, cm) {
|
||||
var pos = ts.jumpStack.pop(), doc = pos && ts.docs[pos.file];
|
||||
if (!doc) return;
|
||||
moveTo(ts, findDoc(ts, cm.getDoc()), doc, pos.start, pos.end);
|
||||
}
|
||||
|
||||
function moveTo(ts, curDoc, doc, start, end) {
|
||||
doc.doc.setSelection(end, start);
|
||||
if (curDoc != doc && ts.options.switchToDoc) {
|
||||
closeArgHints(ts);
|
||||
ts.options.switchToDoc(doc.name);
|
||||
}
|
||||
}
|
||||
|
||||
// The {line,ch} representation of positions makes this rather awkward.
|
||||
function findContext(doc, data) {
|
||||
var before = data.context.slice(0, data.contextOffset).split("\n");
|
||||
var startLine = data.start.line - (before.length - 1);
|
||||
var start = Pos(startLine, (before.length == 1 ? data.start.ch : doc.getLine(startLine).length) - before[0].length);
|
||||
|
||||
var text = doc.getLine(startLine).slice(start.ch);
|
||||
for (var cur = startLine + 1; cur < doc.lineCount() && text.length < data.context.length; ++cur)
|
||||
text += "\n" + doc.getLine(cur);
|
||||
if (text.slice(0, data.context.length) == data.context) return data;
|
||||
|
||||
var cursor = doc.getSearchCursor(data.context, 0, false);
|
||||
var nearest, nearestDist = Infinity;
|
||||
while (cursor.findNext()) {
|
||||
var from = cursor.from(), dist = Math.abs(from.line - start.line) * 10000;
|
||||
if (!dist) dist = Math.abs(from.ch - start.ch);
|
||||
if (dist < nearestDist) { nearest = from; nearestDist = dist; }
|
||||
}
|
||||
if (!nearest) return null;
|
||||
|
||||
if (before.length == 1)
|
||||
nearest.ch += before[0].length;
|
||||
else
|
||||
nearest = Pos(nearest.line + (before.length - 1), before[before.length - 1].length);
|
||||
if (data.start.line == data.end.line)
|
||||
var end = Pos(nearest.line, nearest.ch + (data.end.ch - data.start.ch));
|
||||
else
|
||||
var end = Pos(nearest.line + (data.end.line - data.start.line), data.end.ch);
|
||||
return {start: nearest, end: end};
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
// Variable renaming
|
||||
|
||||
function rename(ts, cm) {
|
||||
var token = cm.getTokenAt(cm.getCursor());
|
||||
if (!/\w/.test(token.string)) showError(ts, cm, "Not at a variable");
|
||||
dialog(cm, "New name for " + token.string, function(newName) {
|
||||
ts.request(cm, {type: "rename", newName: newName, fullDocs: true}, function(error, data) {
|
||||
if (error) return showError(ts, cm, error);
|
||||
applyChanges(ts, data.changes);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var nextChangeOrig = 0;
|
||||
function applyChanges(ts, changes) {
|
||||
var perFile = Object.create(null);
|
||||
for (var i = 0; i < changes.length; ++i) {
|
||||
var ch = changes[i];
|
||||
(perFile[ch.file] || (perFile[ch.file] = [])).push(ch);
|
||||
}
|
||||
for (var file in perFile) {
|
||||
var known = ts.docs[file], chs = perFile[file];;
|
||||
if (!known) continue;
|
||||
chs.sort(function(a, b) { return cmpPos(b.start, a.start); });
|
||||
var origin = "*rename" + (++nextChangeOrig);
|
||||
for (var i = 0; i < chs.length; ++i) {
|
||||
var ch = chs[i];
|
||||
known.doc.replaceRange(ch.text, ch.start, ch.end, origin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generic request-building helper
|
||||
|
||||
function buildRequest(ts, doc, query, pos) {
|
||||
var files = [], offsetLines = 0, allowFragments = !query.fullDocs;
|
||||
if (!allowFragments) delete query.fullDocs;
|
||||
if (typeof query == "string") query = {type: query};
|
||||
query.lineCharPositions = true;
|
||||
if (query.end == null) {
|
||||
query.end = pos || doc.doc.getCursor("end");
|
||||
if (doc.doc.somethingSelected())
|
||||
query.start = doc.doc.getCursor("start");
|
||||
}
|
||||
var startPos = query.start || query.end;
|
||||
|
||||
if (doc.changed) {
|
||||
if (doc.doc.lineCount() > bigDoc && allowFragments !== false &&
|
||||
doc.changed.to - doc.changed.from < 100 &&
|
||||
doc.changed.from <= startPos.line && doc.changed.to > query.end.line) {
|
||||
files.push(getFragmentAround(doc, startPos, query.end));
|
||||
query.file = "#0";
|
||||
var offsetLines = files[0].offsetLines;
|
||||
if (query.start != null) query.start = Pos(query.start.line - -offsetLines, query.start.ch);
|
||||
query.end = Pos(query.end.line - offsetLines, query.end.ch);
|
||||
} else {
|
||||
files.push({type: "full",
|
||||
name: doc.name,
|
||||
text: docValue(ts, doc)});
|
||||
query.file = doc.name;
|
||||
doc.changed = null;
|
||||
}
|
||||
} else {
|
||||
query.file = doc.name;
|
||||
}
|
||||
for (var name in ts.docs) {
|
||||
var cur = ts.docs[name];
|
||||
if (cur.changed && cur != doc) {
|
||||
files.push({type: "full", name: cur.name, text: docValue(ts, cur)});
|
||||
cur.changed = null;
|
||||
}
|
||||
}
|
||||
|
||||
return {query: query, files: files};
|
||||
}
|
||||
|
||||
function getFragmentAround(data, start, end) {
|
||||
var doc = data.doc;
|
||||
var minIndent = null, minLine = null, endLine, tabSize = 4;
|
||||
for (var p = start.line - 1, min = Math.max(0, p - 50); p >= min; --p) {
|
||||
var line = doc.getLine(p), fn = line.search(/\bfunction\b/);
|
||||
if (fn < 0) continue;
|
||||
var indent = CodeMirror.countColumn(line, null, tabSize);
|
||||
if (minIndent != null && minIndent <= indent) continue;
|
||||
minIndent = indent;
|
||||
minLine = p;
|
||||
}
|
||||
if (minLine == null) minLine = min;
|
||||
var max = Math.min(doc.lastLine(), end.line + 20);
|
||||
if (minIndent == null || minIndent == CodeMirror.countColumn(doc.getLine(start.line), null, tabSize))
|
||||
endLine = max;
|
||||
else for (endLine = end.line + 1; endLine < max; ++endLine) {
|
||||
var indent = CodeMirror.countColumn(doc.getLine(endLine), null, tabSize);
|
||||
if (indent <= minIndent) break;
|
||||
}
|
||||
var from = Pos(minLine, 0);
|
||||
|
||||
return {type: "part",
|
||||
name: data.name,
|
||||
offsetLines: from.line,
|
||||
text: doc.getRange(from, Pos(endLine, 0))};
|
||||
}
|
||||
|
||||
// Generic utilities
|
||||
|
||||
function cmpPos(a, b) { return a.line - b.line || a.ch - b.ch; }
|
||||
|
||||
function elt(tagname, cls /*, ... elts*/) {
|
||||
var e = document.createElement(tagname);
|
||||
if (cls) e.className = cls;
|
||||
for (var i = 2; i < arguments.length; ++i) {
|
||||
var elt = arguments[i];
|
||||
if (typeof elt == "string") elt = document.createTextNode(elt);
|
||||
e.appendChild(elt);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
function dialog(cm, text, f) {
|
||||
if (cm.openDialog)
|
||||
cm.openDialog(text + ": <input type=text>", f);
|
||||
else
|
||||
f(prompt(text, ""));
|
||||
}
|
||||
|
||||
// Tooltips
|
||||
|
||||
function tempTooltip(cm, content) {
|
||||
var where = cm.cursorCoords();
|
||||
var tip = makeTooltip(where.right + 1, where.bottom, content);
|
||||
function clear() {
|
||||
if (!tip.parentNode) return;
|
||||
cm.off("cursorActivity", clear);
|
||||
fadeOut(tip);
|
||||
}
|
||||
setTimeout(clear, 1700);
|
||||
cm.on("cursorActivity", clear);
|
||||
}
|
||||
|
||||
function makeTooltip(x, y, content) {
|
||||
var node = elt("div", cls + "tooltip", content);
|
||||
node.style.left = x + "px";
|
||||
node.style.top = y + "px";
|
||||
document.body.appendChild(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
function remove(node) {
|
||||
var p = node && node.parentNode;
|
||||
if (p) p.removeChild(node);
|
||||
}
|
||||
|
||||
function fadeOut(tooltip) {
|
||||
tooltip.style.opacity = "0";
|
||||
setTimeout(function() { remove(tooltip); }, 1100);
|
||||
}
|
||||
|
||||
function showError(ts, cm, msg) {
|
||||
if (ts.options.showError)
|
||||
ts.options.showError(cm, msg);
|
||||
else
|
||||
tempTooltip(cm, String(msg));
|
||||
}
|
||||
|
||||
function closeArgHints(ts) {
|
||||
if (ts.activeArgHints) { remove(ts.activeArgHints); ts.activeArgHints = null; }
|
||||
}
|
||||
|
||||
function docValue(ts, doc) {
|
||||
var val = doc.doc.getValue();
|
||||
if (ts.options.fileFilter) val = ts.options.fileFilter(val, doc.name, doc.doc);
|
||||
return val;
|
||||
}
|
||||
|
||||
// Worker wrapper
|
||||
|
||||
function WorkerServer(ts) {
|
||||
var worker = new Worker(ts.options.workerScript);
|
||||
worker.postMessage({type: "init",
|
||||
defs: ts.options.defs,
|
||||
plugins: ts.options.plugins,
|
||||
scripts: ts.options.workerDeps});
|
||||
var msgId = 0, pending = {};
|
||||
|
||||
function send(data, c) {
|
||||
if (c) {
|
||||
data.id = ++msgId;
|
||||
pending[msgId] = c;
|
||||
}
|
||||
worker.postMessage(data);
|
||||
}
|
||||
worker.onmessage = function(e) {
|
||||
var data = e.data;
|
||||
if (data.type == "getFile") {
|
||||
getFile(ts, data.name, function(err, text) {
|
||||
send({type: "getFile", err: String(err), text: text, id: data.id});
|
||||
});
|
||||
} else if (data.type == "debug") {
|
||||
console.log(data.message);
|
||||
} else if (data.id && pending[data.id]) {
|
||||
pending[data.id](data.err, data.body);
|
||||
delete pending[data.id];
|
||||
}
|
||||
};
|
||||
worker.onerror = function(e) {
|
||||
for (var id in pending) pending[id](e);
|
||||
pending = {};
|
||||
};
|
||||
|
||||
this.addFile = function(name, text) { send({type: "add", name: name, text: text}); };
|
||||
this.delFile = function(name) { send({type: "del", name: name}); };
|
||||
this.request = function(body, c) { send({type: "req", body: body}, c); };
|
||||
}
|
||||
})();
|
|
@ -150,7 +150,8 @@ function Editor(config) {
|
|||
styleActiveLine: true,
|
||||
autoCloseBrackets: "()[]{}''\"\"",
|
||||
autoCloseEnabled: useAutoClose,
|
||||
theme: "mozilla"
|
||||
theme: "mozilla",
|
||||
autocomplete: false
|
||||
};
|
||||
|
||||
// Additional shortcuts.
|
||||
|
@ -336,6 +337,17 @@ Editor.prototype = {
|
|||
return this.getOption("mode");
|
||||
},
|
||||
|
||||
/**
|
||||
* Load a script into editor's containing window.
|
||||
*/
|
||||
loadScript: function (url) {
|
||||
if (!this.container) {
|
||||
throw new Error("Can't load a script until the editor is loaded.")
|
||||
}
|
||||
let win = this.container.contentWindow.wrappedJSObject;
|
||||
Services.scriptloader.loadSubScript(url, win, "utf8");
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the value of a currently used highlighting mode.
|
||||
* See Editor.modes for the list of all suppoert modes.
|
||||
|
@ -822,6 +834,19 @@ Editor.prototype = {
|
|||
cm.refresh();
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets up autocompletion for the editor. Lazily imports the required
|
||||
* dependencies because they vary by editor mode.
|
||||
*/
|
||||
setupAutoCompletion: function (options = {}) {
|
||||
if (this.config.autocomplete) {
|
||||
this.extend(require("./autocomplete"));
|
||||
// The autocomplete module will overwrite this.setupAutoCompletion with
|
||||
// a mode specific autocompletion handler.
|
||||
this.setupAutoCompletion(options);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Extends an instance of the Editor object with additional
|
||||
* functions. Each function will be called with context as
|
||||
|
|
|
@ -262,17 +262,16 @@ StyleSheetEditor.prototype = {
|
|||
readOnly: false,
|
||||
autoCloseBrackets: "{}()[]",
|
||||
extraKeys: this._getKeyBindings(),
|
||||
contextMenu: "sourceEditorContextMenu"
|
||||
contextMenu: "sourceEditorContextMenu",
|
||||
autocomplete: Services.prefs.getBoolPref(AUTOCOMPLETION_PREF)
|
||||
};
|
||||
let sourceEditor = new Editor(config);
|
||||
|
||||
sourceEditor.on("dirty-change", this._onPropertyChange);
|
||||
|
||||
return sourceEditor.appendTo(inputElement).then(() => {
|
||||
if (Services.prefs.getBoolPref(AUTOCOMPLETION_PREF)) {
|
||||
sourceEditor.extend(AutoCompleter);
|
||||
sourceEditor.setupAutoCompletion(this.walker);
|
||||
}
|
||||
sourceEditor.setupAutoCompletion({ walker: this.walker });
|
||||
|
||||
sourceEditor.on("save", () => {
|
||||
this.saveToFile();
|
||||
});
|
||||
|
|
|
@ -123,7 +123,7 @@ function testState() {
|
|||
|
||||
if (key == 'Ctrl+Space') {
|
||||
key = " ";
|
||||
mods.accelKey = true;
|
||||
mods.ctrlKey = true;
|
||||
}
|
||||
else if (key == "VK_RETURN" && entered) {
|
||||
evt = "popup-hidden";
|
||||
|
|
|
@ -395,7 +395,6 @@ let UI = {
|
|||
if (this.toolboxPromise) {
|
||||
this.toolboxPromise.then(toolbox => {
|
||||
toolbox.destroy();
|
||||
document.querySelector("#action-button-debug").removeAttribute("active");
|
||||
this.toolboxPromise = null;
|
||||
}, this.console.error);
|
||||
}
|
||||
|
@ -436,6 +435,7 @@ let UI = {
|
|||
|
||||
let splitter = document.querySelector(".devtools-horizontal-splitter");
|
||||
splitter.setAttribute("hidden", "true");
|
||||
document.querySelector("#action-button-debug").removeAttribute("active");
|
||||
},
|
||||
|
||||
console: {
|
||||
|
|
|
@ -119,7 +119,7 @@
|
|||
<popupset>
|
||||
|
||||
<!-- App panel -->
|
||||
<panel id="project-panel" type="arrow" position="bottomcenter topleft" consumeoutsideclicks="true">
|
||||
<panel id="project-panel" type="arrow" position="bottomcenter topleft" consumeoutsideclicks="true" animate="false">
|
||||
<vbox flex="1">
|
||||
<toolbarbutton class="panel-item project-panel-item-newapp" command="cmd_newApp"/>
|
||||
<toolbarbutton class="panel-item project-panel-item-openpackaged" command="cmd_importPackagedApp"/>
|
||||
|
@ -132,7 +132,7 @@
|
|||
</panel>
|
||||
|
||||
<!-- Runtime panel -->
|
||||
<panel id="runtime-panel" type="arrow" position="bottomcenter topright" consumeoutsideclicks="true">
|
||||
<panel id="runtime-panel" type="arrow" position="bottomcenter topright" consumeoutsideclicks="true" animate="false">
|
||||
<vbox flex="1">
|
||||
<label class="panel-header">&runtimePanel_USBDevices;</label>
|
||||
<vbox id="runtime-panel-usbruntime"></vbox>
|
||||
|
|
|
@ -118,6 +118,12 @@ exports.AppManager = AppManager = {
|
|||
this._runningApps.delete(manifestURL);
|
||||
this.checkIfProjectIsRunning();
|
||||
});
|
||||
|
||||
client.addListener("appUninstall", (type, { manifestURL }) => {
|
||||
AppManager.console.log("App uninstall: " + manifestURL);
|
||||
this._runningApps.delete(manifestURL);
|
||||
this.checkIfProjectIsRunning();
|
||||
});
|
||||
},
|
||||
_unlistenToApps: function() {
|
||||
// Is that even possible?
|
||||
|
|
|
@ -82,3 +82,11 @@ moveLineUp.commandkey=Alt-Up
|
|||
# LOCALIZATION NOTE (moveLineDown.commandkey): This is the key to use to move
|
||||
# the selected lines down.
|
||||
moveLineDown.commandkey=Alt-Down
|
||||
|
||||
# LOCALIZATION NOTE (autocomplete.commandkey): This is the key to use
|
||||
# in conjunction with Ctrl for autocompletion.
|
||||
autocompletion.commandkey=Space
|
||||
|
||||
# LOCALIZATION NOTE (showInformation.commandkey): This is the key to use to
|
||||
# show more information, like type inference.
|
||||
showInformation.commandkey=Shift-Space
|
||||
|
|
|
@ -10,7 +10,12 @@ this.EXPORTED_SYMBOLS = [
|
|||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
const INBOUND_MESSAGE = "ContentSearch";
|
||||
const OUTBOUND_MESSAGE = INBOUND_MESSAGE;
|
||||
|
@ -59,7 +64,9 @@ this.ContentSearch = {
|
|||
receiveMessage: function (msg) {
|
||||
let methodName = "on" + msg.data.type;
|
||||
if (methodName in this) {
|
||||
this[methodName](msg, msg.data.data);
|
||||
this._initService().then(() => {
|
||||
this[methodName](msg, msg.data.data);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -96,18 +103,20 @@ this.ContentSearch = {
|
|||
},
|
||||
|
||||
observe: function (subj, topic, data) {
|
||||
switch (topic) {
|
||||
case "browser-search-engine-modified":
|
||||
if (data == "engine-current") {
|
||||
this._broadcast("CurrentEngine", this._currentEngineObj());
|
||||
this._initService().then(() => {
|
||||
switch (topic) {
|
||||
case "browser-search-engine-modified":
|
||||
if (data == "engine-current") {
|
||||
this._broadcast("CurrentEngine", this._currentEngineObj());
|
||||
}
|
||||
else if (data != "engine-default") {
|
||||
// engine-default is always sent with engine-current and isn't
|
||||
// otherwise relevant to content searches.
|
||||
this._broadcast("State", this._currentStateObj());
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (data != "engine-default") {
|
||||
// engine-default is always sent with engine-current and isn't otherwise
|
||||
// relevant to content searches.
|
||||
this._broadcast("State", this._currentStateObj());
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_reply: function (msg, type, data) {
|
||||
|
@ -146,4 +155,13 @@ this.ContentSearch = {
|
|||
logo2xURI: Services.search.currentEngine.getIconURLBySize(130, 52),
|
||||
};
|
||||
},
|
||||
|
||||
_initService: function () {
|
||||
if (!this._initServicePromise) {
|
||||
let deferred = Promise.defer();
|
||||
this._initServicePromise = deferred.promise;
|
||||
Services.search.init(() => deferred.resolve());
|
||||
}
|
||||
return this._initServicePromise;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,173 +0,0 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* 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/. */
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:root {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display : flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#propertyContainer {
|
||||
-moz-user-select: text;
|
||||
overflow: auto;
|
||||
min-height: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.property-view-hidden,
|
||||
.property-content-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.property-view {
|
||||
clear: both;
|
||||
padding: 2px 0 2px 17px;
|
||||
}
|
||||
|
||||
.property-view > * {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.property-name {
|
||||
/* -12px is so the expander triangle isn't pushed up above the property */
|
||||
width: calc(100% - 12px);
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.property-value {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
background-image: url(arrow-e.png);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 5px 8px;
|
||||
background-position: 2px center;
|
||||
padding-left: 10px;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.other-property-value {
|
||||
background-image: url(arrow-e.png);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 5px 8px;
|
||||
background-position: left center;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
@media (min-width: 400px) {
|
||||
.property-name {
|
||||
width: 200px;
|
||||
}
|
||||
.property-value {
|
||||
/* -212px is accounting for the 200px property-name and the 12px triangle */
|
||||
width: calc(100% - 212px);
|
||||
}
|
||||
}
|
||||
|
||||
.property-content {
|
||||
padding-left: 17px;
|
||||
}
|
||||
|
||||
/* From skin */
|
||||
.expander {
|
||||
visibility: hidden;
|
||||
margin-left: -12px!important;
|
||||
}
|
||||
|
||||
.expandable {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.match {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.matchedselectors > p {
|
||||
clear: both;
|
||||
margin: 0 2px 0 0;
|
||||
padding: 2px;
|
||||
overflow-x: hidden;
|
||||
border-style: dotted;
|
||||
border-color: rgba(128,128,128,0.4);
|
||||
border-width: 1px 1px 0 1px;
|
||||
}
|
||||
|
||||
.matchedselectors > p:last-of-type {
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
/* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
|
||||
.rule-text {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.matched {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.parentmatch {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#noResults {
|
||||
font-size: 110%;
|
||||
margin: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.onlyuserstyles {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.legendKey {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.devtools-toolbar {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.link {
|
||||
padding: 0 3px;
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.computedview-colorswatch {
|
||||
border-radius: 50%;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: text-top;
|
||||
-moz-margin-end: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.computedview-colorswatch::before {
|
||||
content: '';
|
||||
background-color: #eee;
|
||||
background-image: linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc),
|
||||
linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc);
|
||||
background-size: 12px 12px;
|
||||
background-position: 0 0, 6px 6px;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
z-index: -1;
|
||||
}
|
|
@ -26,7 +26,7 @@
|
|||
min-height: 18px;
|
||||
}
|
||||
|
||||
#downloads-button[cui-areatype="toolbar"] > #downloads-indicator-anchor > #downloads-indicator-icon:-moz-lwtheme-brighttext {
|
||||
toolbar[brighttext] #downloads-button[cui-areatype="toolbar"]:not([attention]) > #downloads-indicator-anchor > #downloads-indicator-icon {
|
||||
background: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"),
|
||||
0, 198, 18, 180) center no-repeat;
|
||||
}
|
||||
|
@ -49,8 +49,7 @@
|
|||
background-size: 12px;
|
||||
}
|
||||
|
||||
#downloads-button:not([counter]) > #downloads-indicator-anchor >
|
||||
#downloads-button-progress-area > #downloads-indicator-counter:-moz-lwtheme-brighttext {
|
||||
toolbar[brighttext] #downloads-button:not([counter]):not([attention]) > #downloads-indicator-anchor > #downloads-button-progress-area > #downloads-indicator-counter {
|
||||
background-image: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"), 0, 198, 18, 180);
|
||||
}
|
||||
|
||||
|
@ -115,7 +114,7 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
#downloads-indicator-counter:-moz-lwtheme-brighttext {
|
||||
toolbar[brighttext] #downloads-indicator-counter {
|
||||
color: white;
|
||||
text-shadow: 0 0 1px rgba(0,0,0,.7),
|
||||
0 1px 1.5px rgba(0,0,0,.5);
|
||||
|
|
|
@ -237,8 +237,8 @@ browser.jar:
|
|||
skin/classic/browser/devtools/magnifying-glass-light@2x.png (../shared/devtools/images/magnifying-glass-light@2x.png)
|
||||
skin/classic/browser/devtools/itemToggle.png (../shared/devtools/images/itemToggle.png)
|
||||
skin/classic/browser/devtools/itemToggle-light.png (../shared/devtools/images/itemToggle-light.png)
|
||||
skin/classic/browser/devtools/itemArrow-dark-rtl.png (../shared/devtools/images/itemArrow-dark-rtl.png)
|
||||
skin/classic/browser/devtools/itemArrow-dark-ltr.png (../shared/devtools/images/itemArrow-dark-ltr.png)
|
||||
skin/classic/browser/devtools/itemArrow-dark-rtl.svg (../shared/devtools/images/itemArrow-dark-rtl.svg)
|
||||
skin/classic/browser/devtools/itemArrow-dark-ltr.svg (../shared/devtools/images/itemArrow-dark-ltr.svg)
|
||||
skin/classic/browser/devtools/itemArrow-rtl.svg (../shared/devtools/images/itemArrow-rtl.svg)
|
||||
skin/classic/browser/devtools/itemArrow-ltr.svg (../shared/devtools/images/itemArrow-ltr.svg)
|
||||
skin/classic/browser/devtools/background-noise-toolbar.png (../shared/devtools/images/background-noise-toolbar.png)
|
||||
|
@ -301,7 +301,7 @@ browser.jar:
|
|||
skin/classic/browser/devtools/vview-open-inspector@2x.png (../shared/devtools/images/vview-open-inspector@2x.png)
|
||||
skin/classic/browser/devtools/undock@2x.png (../shared/devtools/images/undock@2x.png)
|
||||
skin/classic/browser/devtools/font-inspector.css (../shared/devtools/font-inspector.css)
|
||||
skin/classic/browser/devtools/computedview.css (devtools/computedview.css)
|
||||
skin/classic/browser/devtools/computedview.css (../shared/devtools/computedview.css)
|
||||
skin/classic/browser/devtools/arrow-e.png (../shared/devtools/images/arrow-e.png)
|
||||
skin/classic/browser/devtools/responsiveui-rotate.png (../shared/devtools/responsiveui-rotate.png)
|
||||
skin/classic/browser/devtools/responsiveui-touch.png (../shared/devtools/responsiveui-touch.png)
|
||||
|
|
|
@ -630,14 +630,6 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-ic
|
|||
%include ../shared/toolbarbuttons.inc.css
|
||||
%include ../shared/menupanel.inc.css
|
||||
|
||||
#home-button.bookmark-item {
|
||||
list-style-image: url("chrome://browser/skin/Toolbar.png");
|
||||
}
|
||||
|
||||
#home-button.bookmark-item:not(@inAnyPanel@):-moz-lwtheme-brighttext {
|
||||
list-style-image: url(chrome://browser/skin/Toolbar-inverted.png);
|
||||
}
|
||||
|
||||
#back-button:hover:active:not([disabled="true"]) {
|
||||
-moz-image-region: rect(18px, 36px, 36px, 18px);
|
||||
}
|
||||
|
@ -801,14 +793,12 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-ic
|
|||
to avoid potentially breaking add-on toolbar buttons. */
|
||||
|
||||
:-moz-any(@primaryToolbarButtons@),
|
||||
#home-button.bookmark-item,
|
||||
#bookmarks-menu-button[cui-areatype="toolbar"] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
|
||||
list-style-image: url("chrome://browser/skin/Toolbar@2x.png");
|
||||
}
|
||||
|
||||
:-moz-any(@primaryToolbarButtons@):not(@inAnyPanel@):-moz-lwtheme-brighttext,
|
||||
#home-button.bookmark-item:not(@inAnyPanel@):-moz-lwtheme-brighttext,
|
||||
#bookmarks-menu-button:not(@inAnyPanel@):-moz-lwtheme-brighttext > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
|
||||
toolbar[brighttext] :-moz-any(@primaryToolbarButtons@),
|
||||
toolbar[brighttext] #bookmarks-menu-button[cui-areatype="toolbar"] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
|
||||
list-style-image: url("chrome://browser/skin/Toolbar-inverted@2x.png");
|
||||
}
|
||||
|
||||
|
@ -914,8 +904,8 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-ic
|
|||
-moz-image-region: rect(0, 36px, 36px, 0px);
|
||||
}
|
||||
|
||||
#sync-button[cui-areatype="toolbar"][status="active"]:-moz-lwtheme-brighttext,
|
||||
#sync-button[cui-areatype="toolbar"][status="active"]:-moz-lwtheme-brighttext:hover:active:not([disabled="true"]) {
|
||||
toolbar[brighttext] #sync-button[cui-areatype="toolbar"][status="active"],
|
||||
toolbar[brighttext] #sync-button[cui-areatype="toolbar"][status="active"]:hover:active:not([disabled="true"]) {
|
||||
list-style-image: url("chrome://browser/skin/syncProgress-toolbar-inverted@2x.png");
|
||||
}
|
||||
|
||||
|
|
|
@ -29,11 +29,11 @@
|
|||
0, 198, 18, 180) center no-repeat;
|
||||
}
|
||||
|
||||
#downloads-indicator-icon:-moz-lwtheme-brighttext {
|
||||
toolbar[brighttext] #downloads-indicator-icon {
|
||||
background-image: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"), 0, 198, 18, 180);
|
||||
}
|
||||
|
||||
#downloads-button[attention] #downloads-indicator-icon {
|
||||
#downloads-button[attention] > #downloads-indicator-anchor > #downloads-indicator-icon {
|
||||
background-image: url("chrome://browser/skin/downloads/download-glow.png");
|
||||
}
|
||||
|
||||
|
@ -45,17 +45,17 @@
|
|||
/* In the next few rules, we use :not([counter]) as a shortcut that is
|
||||
equivalent to -moz-any([progress], [paused]). */
|
||||
|
||||
#downloads-button:not([counter]) #downloads-indicator-counter {
|
||||
#downloads-button:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
|
||||
background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
|
||||
0, 198, 18, 180) center no-repeat;
|
||||
background-size: 12px;
|
||||
}
|
||||
|
||||
#downloads-button:not([counter]) #downloads-indicator-counter:-moz-lwtheme-brighttext {
|
||||
toolbar[brighttext] #downloads-button:not([counter]):not([attention]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
|
||||
background-image: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"), 0, 198, 18, 180);
|
||||
}
|
||||
|
||||
#downloads-button:not([counter])[attention] #downloads-indicator-counter {
|
||||
#downloads-button:not([counter])[attention] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
|
||||
background-image: url("chrome://browser/skin/downloads/download-glow.png");
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@
|
|||
background-size: 18px;
|
||||
}
|
||||
|
||||
#downloads-indicator-icon:-moz-lwtheme-brighttext {
|
||||
toolbar[brighttext] #downloads-indicator-icon {
|
||||
background-image: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted@2x.png"), 0, 396, 36, 360);
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@
|
|||
background-image: -moz-image-rect(url("chrome://browser/skin/Toolbar@2x.png"), 0, 396, 36, 360);
|
||||
}
|
||||
|
||||
#downloads-button:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter:-moz-lwtheme-brighttext {
|
||||
toolbar[brighttext] #downloads-button:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
|
||||
background-image: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted@2x.png"),
|
||||
0, 396, 36, 360);
|
||||
}
|
||||
|
|
|
@ -359,8 +359,8 @@ browser.jar:
|
|||
skin/classic/browser/devtools/magnifying-glass-light@2x.png (../shared/devtools/images/magnifying-glass-light@2x.png)
|
||||
skin/classic/browser/devtools/itemToggle.png (../shared/devtools/images/itemToggle.png)
|
||||
skin/classic/browser/devtools/itemToggle-light.png (../shared/devtools/images/itemToggle-light.png)
|
||||
skin/classic/browser/devtools/itemArrow-dark-rtl.png (../shared/devtools/images/itemArrow-dark-rtl.png)
|
||||
skin/classic/browser/devtools/itemArrow-dark-ltr.png (../shared/devtools/images/itemArrow-dark-ltr.png)
|
||||
skin/classic/browser/devtools/itemArrow-dark-rtl.svg (../shared/devtools/images/itemArrow-dark-rtl.svg)
|
||||
skin/classic/browser/devtools/itemArrow-dark-ltr.svg (../shared/devtools/images/itemArrow-dark-ltr.svg)
|
||||
skin/classic/browser/devtools/itemArrow-rtl.svg (../shared/devtools/images/itemArrow-rtl.svg)
|
||||
skin/classic/browser/devtools/itemArrow-ltr.svg (../shared/devtools/images/itemArrow-ltr.svg)
|
||||
skin/classic/browser/devtools/background-noise-toolbar.png (../shared/devtools/images/background-noise-toolbar.png)
|
||||
|
@ -423,7 +423,7 @@ browser.jar:
|
|||
skin/classic/browser/devtools/vview-open-inspector@2x.png (../shared/devtools/images/vview-open-inspector@2x.png)
|
||||
skin/classic/browser/devtools/undock@2x.png (../shared/devtools/images/undock@2x.png)
|
||||
skin/classic/browser/devtools/font-inspector.css (../shared/devtools/font-inspector.css)
|
||||
skin/classic/browser/devtools/computedview.css (devtools/computedview.css)
|
||||
skin/classic/browser/devtools/computedview.css (../shared/devtools/computedview.css)
|
||||
skin/classic/browser/devtools/arrow-e.png (../shared/devtools/images/arrow-e.png)
|
||||
skin/classic/browser/devtools/responsiveui-rotate.png (../shared/devtools/responsiveui-rotate.png)
|
||||
skin/classic/browser/devtools/responsiveui-touch.png (../shared/devtools/responsiveui-touch.png)
|
||||
|
|
|
@ -56,10 +56,8 @@
|
|||
|
||||
.devtools-autocomplete-popup {
|
||||
-moz-appearance: none !important;
|
||||
border: 1px solid hsl(210,11%,10%);
|
||||
box-shadow: 0 1px 0 hsla(209,29%,72%,.25) inset;
|
||||
background-color: transparent;
|
||||
background-image: linear-gradient(to bottom, hsla(209,18%,18%,0.9), hsl(210,11%,16%));
|
||||
border-radius: 3px;
|
||||
overflow-x: hidden;
|
||||
%if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
|
||||
|
@ -110,12 +108,24 @@
|
|||
text-align: right;
|
||||
}
|
||||
|
||||
/* Rest of the light theme */
|
||||
/* Rest of the dark and light theme */
|
||||
|
||||
.devtools-autocomplete-popup,
|
||||
.theme-dark .CodeMirror-hints,
|
||||
.theme-dark .CodeMirror-Tern-tooltip {
|
||||
border: 1px solid hsl(210,11%,10%);
|
||||
background-image: linear-gradient(to bottom, hsla(209,18%,18%,0.9), hsl(210,11%,16%));
|
||||
}
|
||||
|
||||
.devtools-autocomplete-popup.light-theme,
|
||||
.light-theme .CodeMirror-hints,
|
||||
.light-theme .CodeMirror-Tern-tooltip {
|
||||
border: 1px solid hsl(210,24%,90%);
|
||||
background-image: linear-gradient(to bottom, hsla(209,18%,100%,0.9), hsl(210,24%,95%));
|
||||
}
|
||||
|
||||
.devtools-autocomplete-popup.light-theme {
|
||||
border: 1px solid hsl(210,24%,90%);
|
||||
box-shadow: 0 1px 0 hsla(209,29%,90%,.25) inset;
|
||||
background-image: linear-gradient(to bottom, hsla(209,18%,100%,0.9), hsl(210,24%,95%));
|
||||
}
|
||||
|
||||
.devtools-autocomplete-listbox.light-theme > richlistitem[selected],
|
||||
|
|
|
@ -3,22 +3,6 @@
|
|||
* 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/. */
|
||||
|
||||
/* Take away these two :visited rules to get a core dumper */
|
||||
/* See https://bugzilla.mozilla.org/show_bug.cgi?id=575675#c30 */
|
||||
.link,
|
||||
.link:visited {
|
||||
color: #0091ff;
|
||||
}
|
||||
.link,
|
||||
.helplink,
|
||||
.link:visited,
|
||||
.helplink:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
.link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* From content */
|
||||
|
||||
* {
|
||||
|
@ -167,6 +151,25 @@ body {
|
|||
float: right;
|
||||
}
|
||||
|
||||
/* Take away these two :visited rules to get a core dumper */
|
||||
/* See https://bugzilla.mozilla.org/show_bug.cgi?id=575675#c30 */
|
||||
|
||||
.link,
|
||||
.link:visited {
|
||||
color: #0091ff;
|
||||
}
|
||||
|
||||
.link,
|
||||
.helplink,
|
||||
.link:visited,
|
||||
.helplink:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.computedview-colorswatch {
|
||||
border-radius: 50%;
|
||||
width: 1em;
|
||||
|
@ -174,6 +177,7 @@ body {
|
|||
vertical-align: text-top;
|
||||
-moz-margin-end: 5px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.computedview-colorswatch::before {
|
||||
|
@ -185,7 +189,9 @@ body {
|
|||
background-position: 0 0, 6px 6px;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
}
|
|
@ -25,7 +25,8 @@
|
|||
background-color: rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.theme-selected {
|
||||
.theme-selected,
|
||||
.CodeMirror-hint-active {
|
||||
background-color: #1d4f73;
|
||||
color: #f5f7fa; /* Light foreground text */
|
||||
}
|
||||
|
@ -45,7 +46,8 @@
|
|||
* failures in debug builds.
|
||||
*/
|
||||
.theme-link:visited,
|
||||
.cm-s-mozilla .cm-link:visited { /* blue */
|
||||
.cm-s-mozilla .cm-link:visited,
|
||||
.CodeMirror-Tern-type { /* blue */
|
||||
color: #3689b2;
|
||||
}
|
||||
|
||||
|
@ -59,6 +61,10 @@
|
|||
color: #5c6773;
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-unknown:before {
|
||||
background-color: #5c6773;
|
||||
}
|
||||
|
||||
.theme-gutter {
|
||||
background-color: #0f171f;
|
||||
color: #667380;
|
||||
|
@ -77,6 +83,10 @@
|
|||
color: #5c9966;
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-number:before {
|
||||
background-color: #5c9966;
|
||||
}
|
||||
|
||||
.theme-fg-color2,
|
||||
.cm-s-mozilla .cm-attribute,
|
||||
.cm-s-mozilla .cm-variable,
|
||||
|
@ -87,6 +97,10 @@
|
|||
color: #3689b2;
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-object:before {
|
||||
background-color: #3689b2;
|
||||
}
|
||||
|
||||
.theme-fg-color3,
|
||||
.cm-s-mozilla .cm-builtin,
|
||||
.cm-s-mozilla .cm-tag,
|
||||
|
@ -95,6 +109,10 @@
|
|||
color: #a673bf;
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-array:before {
|
||||
background-color: #a673bf;
|
||||
}
|
||||
|
||||
.theme-fg-color4 { /* purple/violet */
|
||||
color: #6270b2;
|
||||
}
|
||||
|
@ -108,10 +126,16 @@
|
|||
.theme-fg-color6,
|
||||
.cm-s-mozilla .cm-string,
|
||||
.cm-s-mozilla .cm-string-2,
|
||||
.variable-or-property .token-string { /* Orange */
|
||||
.variable-or-property .token-string,
|
||||
.CodeMirror-Tern-farg { /* Orange */
|
||||
color: #b26b47;
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-string:before,
|
||||
.CodeMirror-Tern-completion-fn:before {
|
||||
background-color: #b26b47;
|
||||
}
|
||||
|
||||
.theme-fg-color7,
|
||||
.cm-s-mozilla .cm-atom,
|
||||
.cm-s-mozilla .cm-quote,
|
||||
|
@ -122,6 +146,10 @@
|
|||
color: #bf5656;
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-bool:before {
|
||||
background-color: #bf5656;
|
||||
}
|
||||
|
||||
.variable-or-property .token-domnode {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
@ -334,4 +362,16 @@ div.CodeMirror span.eval-text {
|
|||
color: rgba(184, 200, 217, 1);
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-fname {
|
||||
color: #f7f7f7;
|
||||
}
|
||||
|
||||
.CodeMirror-hints,
|
||||
.CodeMirror-Tern-tooltip {
|
||||
box-shadow: 0 0 4px rgba(255, 255, 255, .3);
|
||||
background-color: #0f171f;
|
||||
color: #8fa1b2;
|
||||
}
|
||||
|
||||
|
||||
%include toolbars.inc.css
|
||||
|
|
Двоичные данные
browser/themes/shared/devtools/images/itemArrow-dark-ltr.png
Двоичные данные
browser/themes/shared/devtools/images/itemArrow-dark-ltr.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 2.8 KiB |
|
@ -0,0 +1,4 @@
|
|||
<svg width="7" xmlns="http://www.w3.org/2000/svg" height="12" viewBox="0 0 7 12" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 7 12">
|
||||
<path fill="#181D20" d="M7,11.6 7,.4 1.5,6z"/>
|
||||
<path fill="#000" d="M7,0 6,0 0,6 6,12 7,12 7,11.6 1.5,6 7,.4z"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 278 B |
Двоичные данные
browser/themes/shared/devtools/images/itemArrow-dark-rtl.png
Двоичные данные
browser/themes/shared/devtools/images/itemArrow-dark-rtl.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 2.8 KiB |
|
@ -0,0 +1,4 @@
|
|||
<svg width="7" xmlns="http://www.w3.org/2000/svg" height="12" viewBox="0 0 7 12" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 7 12">
|
||||
<path fill="#181D20" d="M0,11.6 0,.4 5.5,6z"/>
|
||||
<path fill="#000" d="M1,0 0,0 0,.4 5.5,6 0,11.6 0,12 1,12 7,6z"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 280 B |
|
@ -25,7 +25,8 @@
|
|||
background: #EFEFEF;
|
||||
}
|
||||
|
||||
.theme-selected {
|
||||
.theme-selected,
|
||||
.CodeMirror-hint-active {
|
||||
background-color: #4c9ed9;
|
||||
color: #f5f7fa; /* Light foreground text */
|
||||
}
|
||||
|
@ -36,7 +37,8 @@
|
|||
}
|
||||
|
||||
.theme-link,
|
||||
.cm-s-mozilla .cm-link { /* blue */
|
||||
.cm-s-mozilla .cm-link,
|
||||
.CodeMirror-Tern-type { /* blue */
|
||||
color: hsl(208,56%,40%);
|
||||
}
|
||||
|
||||
|
@ -58,6 +60,10 @@
|
|||
color: hsl(90,2%,46%);
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-unknown:before {
|
||||
background-color: hsl(90,2%,46%);
|
||||
}
|
||||
|
||||
.theme-gutter {
|
||||
background-color: hsl(0,0%,90%);
|
||||
color: #667380;
|
||||
|
@ -76,6 +82,10 @@
|
|||
color: hsl(72,100%,27%);
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-number:before {
|
||||
background-color: hsl(72,100%,27%);
|
||||
}
|
||||
|
||||
.theme-fg-color2,
|
||||
.cm-s-mozilla .cm-attribute,
|
||||
.cm-s-mozilla .cm-builtin,
|
||||
|
@ -86,12 +96,20 @@
|
|||
color: hsl(208,56%,40%);
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-object:before {
|
||||
background-color: hsl(208,56%,40%);
|
||||
}
|
||||
|
||||
.theme-fg-color3,
|
||||
.cm-s-mozilla .cm-variable,
|
||||
.cm-s-mozilla .cm-tag,
|
||||
.cm-s-mozilla .cm-header,
|
||||
.variables-view-property > .title > .name { /* dark blue */
|
||||
color: hsl(208,81%,21%)
|
||||
color: hsl(208,81%,21%);
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-array:before { /* dark blue */
|
||||
background-color: hsl(208,81%,21%);
|
||||
}
|
||||
|
||||
.theme-fg-color4 { /* Orange */
|
||||
|
@ -107,10 +125,16 @@
|
|||
.theme-fg-color6,
|
||||
.cm-s-mozilla .cm-string,
|
||||
.cm-s-mozilla .cm-string-2,
|
||||
.variable-or-property .token-string { /* Orange */
|
||||
.variable-or-property .token-string,
|
||||
.CodeMirror-Tern-farg { /* Orange */
|
||||
color: hsl(24,85%,39%);
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-string:before,
|
||||
.CodeMirror-Tern-completion-fn:before {
|
||||
background-color: hsl(24,85%,39%);
|
||||
}
|
||||
|
||||
.theme-fg-color7,
|
||||
.cm-s-mozilla .cm-atom,
|
||||
.cm-s-mozilla .cm-quote,
|
||||
|
@ -121,6 +145,10 @@
|
|||
color: #bf5656;
|
||||
}
|
||||
|
||||
.CodeMirror-Tern-completion-bool:before {
|
||||
background-color: #bf5656;
|
||||
}
|
||||
|
||||
.variable-or-property .token-domnode {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
@ -337,4 +365,11 @@ div.CodeMirror span.eval-text {
|
|||
border-color: #aaa; /* Needed for responsive container at low width. */
|
||||
}
|
||||
|
||||
.CodeMirror-hints,
|
||||
.CodeMirror-Tern-tooltip {
|
||||
box-shadow: 0 0 4px rgba(128, 128, 128, .5);
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
|
||||
%include toolbars.inc.css
|
||||
|
|
|
@ -119,6 +119,7 @@
|
|||
vertical-align: text-top;
|
||||
-moz-margin-end: 5px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ruleview-colorswatch::before {
|
||||
|
@ -130,8 +131,10 @@
|
|||
background-position: 0 0, 6px 6px;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -90,13 +90,13 @@
|
|||
}
|
||||
|
||||
.theme-dark .splitview-nav > li.splitview-active {
|
||||
background-image: url(itemArrow-dark-ltr.png),
|
||||
background-image: url(itemArrow-dark-ltr.svg),
|
||||
linear-gradient(@smw_marginDark@, @smw_marginDark@),
|
||||
linear-gradient(#1d4f73, #1d4f73);
|
||||
}
|
||||
|
||||
.theme-dark .splitview-nav > li.splitview-active:-moz-locale-dir(rtl) {
|
||||
background-image: url(itemArrow-dark-rtl.png),
|
||||
background-image: url(itemArrow-dark-rtl.svg),
|
||||
linear-gradient(@smw_marginDark@, @smw_marginDark@),
|
||||
linear-gradient(#1d4f73, #1d4f73);
|
||||
}
|
||||
|
|
|
@ -478,11 +478,11 @@
|
|||
}
|
||||
|
||||
.theme-dark .side-menu-widget-item.selected > .side-menu-widget-item-arrow:-moz-locale-dir(ltr) {
|
||||
background-image: url(itemArrow-dark-ltr.png), linear-gradient(to right, @smw_marginDark@, @smw_marginDark@);
|
||||
background-image: url(itemArrow-dark-ltr.svg), linear-gradient(to right, @smw_marginDark@, @smw_marginDark@);
|
||||
}
|
||||
|
||||
.theme-dark .side-menu-widget-item.selected > .side-menu-widget-item-arrow:-moz-locale-dir(rtl) {
|
||||
background-image: url(itemArrow-dark-rtl.png), linear-gradient(to right, @smw_marginDark@, @smw_marginDark@);
|
||||
background-image: url(itemArrow-dark-rtl.svg), linear-gradient(to right, @smw_marginDark@, @smw_marginDark@);
|
||||
}
|
||||
|
||||
.theme-light .side-menu-widget-item.selected > .side-menu-widget-item-arrow:-moz-locale-dir(ltr) {
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
list-style-image: url("chrome://browser/skin/Toolbar.png");
|
||||
}
|
||||
|
||||
:-moz-any(@primaryToolbarButtons@):not(@inAnyPanel@):-moz-lwtheme-brighttext,
|
||||
#bookmarks-menu-button:not(@inAnyPanel@):-moz-lwtheme-brighttext > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
|
||||
toolbar[brighttext] :-moz-any(@primaryToolbarButtons@),
|
||||
toolbar[brighttext] #bookmarks-menu-button > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
|
||||
list-style-image: url(chrome://browser/skin/Toolbar-inverted.png);
|
||||
}
|
||||
|
||||
|
@ -64,8 +64,8 @@
|
|||
-moz-image-region: rect(0, 18px, 18px, 0px);
|
||||
}
|
||||
|
||||
#sync-button[cui-areatype="toolbar"][status="active"]:-moz-lwtheme-brighttext,
|
||||
#sync-button[cui-areatype="toolbar"][status="active"]:-moz-lwtheme-brighttext:hover:active:not([disabled="true"]) {
|
||||
toolbar[brighttext] #sync-button[status="active"],
|
||||
toolbar[brighttext] #sync-button[status="active"]:hover:active:not([disabled="true"]) {
|
||||
list-style-image: url("chrome://browser/skin/syncProgress-toolbar-inverted.png");
|
||||
}
|
||||
|
||||
|
|
|
@ -165,27 +165,6 @@
|
|||
color: white;
|
||||
}
|
||||
|
||||
#main-window[darkwindowframe="true"] :-moz-any(#toolbar-menubar, #TabsToolbar) :-moz-any(@primaryToolbarButtons@):not(:-moz-lwtheme):not(:-moz-window-inactive),
|
||||
#main-window[darkwindowframe="true"] :-moz-any(#toolbar-menubar, #TabsToolbar) #bookmarks-menu-button:not(:-moz-lwtheme) > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:not(:-moz-window-inactive) {
|
||||
list-style-image: url(chrome://browser/skin/Toolbar-inverted.png);
|
||||
}
|
||||
|
||||
#main-window[darkwindowframe="true"] .tabs-newtab-button:not(:-moz-lwtheme):not(:-moz-window-inactive),
|
||||
#main-window[darkwindowframe="true"] :-moz-any(#toolbar-menubar, #TabsToolbar) > #new-tab-button:not(:-moz-lwtheme):not(:-moz-window-inactive),
|
||||
#main-window[darkwindowframe="true"] :-moz-any(#toolbar-menubar, #TabsToolbar) > toolbarpaletteitem > #new-tab-button:not(:-moz-lwtheme):not(:-moz-window-inactive) {
|
||||
list-style-image: url(chrome://browser/skin/tabbrowser/newtab-inverted.png);
|
||||
}
|
||||
|
||||
#main-window[darkwindowframe="true"] .tab-close-button:not(:-moz-any(:hover, [selected="true"], :-moz-lwtheme, :-moz-window-inactive)) {
|
||||
-moz-image-region: rect(0, 64px, 16px, 48px);
|
||||
}
|
||||
|
||||
#main-window[darkwindowframe="true"] :-moz-any(#toolbar-menubar, #TabsToolbar) > #sync-button[status="active"]:not(:-moz-lwtheme),
|
||||
#main-window[darkwindowframe="true"] :-moz-any(#toolbar-menubar, #TabsToolbar) > toolbarpaletteitem > #sync-button[status="active"]:not(:-moz-lwtheme) {
|
||||
list-style-image: url("chrome://browser/skin/syncProgress-toolbar-inverted.png");
|
||||
}
|
||||
|
||||
|
||||
#toolbar-menubar:not(:-moz-lwtheme) {
|
||||
text-shadow: 0 0 .5em white, 0 0 .5em white, 0 1px 0 rgba(255,255,255,.4);
|
||||
}
|
||||
|
@ -283,21 +262,6 @@
|
|||
background-color: #556;
|
||||
}
|
||||
|
||||
/* Use inverted icons for non-fogged glassed toolbars */
|
||||
#toolbar-menubar > toolbarpaletteitem > #bookmarks-menu-button > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:not(:-moz-lwtheme),
|
||||
#toolbar-menubar > #bookmarks-menu-button > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:not(:-moz-lwtheme),
|
||||
#toolbar-menubar > toolbarpaletteitem > toolbaritem > :-moz-any(@nestedButtons@):not(:-moz-lwtheme),
|
||||
#toolbar-menubar > toolbaritem > :-moz-any(@nestedButtons@):not(:-moz-lwtheme),
|
||||
#toolbar-menubar > toolbarpaletteitem > :-moz-any(@primaryToolbarButtons@):not(:-moz-lwtheme),
|
||||
#toolbar-menubar > :-moz-any(@primaryToolbarButtons@):not(:-moz-lwtheme) {
|
||||
list-style-image: url("chrome://browser/skin/Toolbar-inverted.png");
|
||||
}
|
||||
|
||||
#toolbar-menubar > #sync-button[status="active"]:not(:-moz-lwtheme),
|
||||
#toolbar-menubar > toolbarpaletteitem > #sync-button[status="active"]:not(:-moz-lwtheme) {
|
||||
list-style-image: url("chrome://browser/skin/syncProgress-toolbar-inverted.png");
|
||||
}
|
||||
|
||||
/* Glass Fog */
|
||||
|
||||
#TabsToolbar:not(:-moz-lwtheme) {
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
margin-top: 3px;
|
||||
}
|
||||
|
||||
#main-window[tabsintitlebar][sizemode="normal"][chromehidden~="menubar"] #toolbar-menubar ~ #TabsToolbar,
|
||||
#main-window[tabsintitlebar][sizemode="normal"] #toolbar-menubar[autohide="true"][inactive] ~ #TabsToolbar {
|
||||
#main-window[tabsintitlebar][sizemode="normal"]:not([inFullscreen])[chromehidden~="menubar"] #toolbar-menubar ~ #TabsToolbar,
|
||||
#main-window[tabsintitlebar][sizemode="normal"]:not([inFullscreen]) #toolbar-menubar[autohide="true"][inactive] ~ #TabsToolbar {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
|
@ -198,10 +198,6 @@
|
|||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) .tab-close-button:not(:-moz-any(:hover,:-moz-lwtheme,[selected="true"])) {
|
||||
-moz-image-region: rect(0, 64px, 16px, 48px);
|
||||
}
|
||||
|
||||
#main-window[tabsintitlebar][sizemode="normal"] #titlebar-content:-moz-lwtheme {
|
||||
/* Render a window top border: */
|
||||
background-image: linear-gradient(to bottom,
|
||||
|
@ -575,8 +571,8 @@ menuitem.bookmark-item {
|
|||
list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow.png");
|
||||
}
|
||||
|
||||
toolbar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker:-moz-lwtheme-brighttext,
|
||||
toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:-moz-lwtheme-brighttext {
|
||||
toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menu-dropmarker,
|
||||
toolbar[brighttext] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
|
||||
list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png");
|
||||
}
|
||||
|
||||
|
@ -1000,35 +996,6 @@ toolbarbutton[sdk-button="true"][cui-areatype="toolbar"] > .toolbarbutton-icon {
|
|||
list-style-image: url("chrome://browser/skin/menu-forward.png") !important;
|
||||
}
|
||||
|
||||
#home-button.bookmark-item {
|
||||
list-style-image: url("chrome://browser/skin/Toolbar.png");
|
||||
}
|
||||
|
||||
%ifndef WINDOWS_AERO
|
||||
@media (-moz-windows-theme: luna-silver) {
|
||||
#home-button.bookmark-item {
|
||||
list-style-image: url("chrome://browser/skin/Toolbar-lunaSilver.png");
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) :-moz-any(#TabsToolbar, #toolbar-menubar) > #bookmarks-menu-button > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-system-metric(windows-classic):not(:-moz-lwtheme),
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) :-moz-any(#TabsToolbar, #toolbar-menubar) > toolbarpaletteitem > #bookmarks-menu-button > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-system-metric(windows-classic):not(:-moz-lwtheme),
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) :-moz-any(#TabsToolbar, #toolbar-menubar) > toolbarpaletteitem > toolbaritem > :-moz-any(@nestedButtons@):-moz-system-metric(windows-classic):not(:-moz-lwtheme),
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) :-moz-any(#TabsToolbar, #toolbar-menubar) > toolbaritem > :-moz-any(@nestedButtons@):-moz-system-metric(windows-classic):not(:-moz-lwtheme),
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) :-moz-any(#TabsToolbar, #toolbar-menubar) > toolbarpaletteitem > :-moz-any(@primaryToolbarButtons@):-moz-system-metric(windows-classic):not(:-moz-lwtheme),
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) :-moz-any(#TabsToolbar, #toolbar-menubar) > :-moz-any(@primaryToolbarButtons@):-moz-system-metric(windows-classic):not(:-moz-lwtheme),
|
||||
#home-button.bookmark-item:-moz-lwtheme-brighttext {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
list-style-image: url("chrome://browser/skin/Toolbar-inverted.png");
|
||||
}
|
||||
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) :-moz-any(#TabsToolbar, #toolbar-menubar) > #sync-button[status="active"]:-moz-system-metric(windows-classic):not(:-moz-lwtheme),
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) :-moz-any(#TabsToolbar, #toolbar-menubar) > toolbarpaletteitem > #sync-button[status="active"]:-moz-system-metric(windows-classic):not(:-moz-lwtheme) {
|
||||
list-style-image: url("chrome://browser/skin/syncProgress-toolbar-inverted.png");
|
||||
}
|
||||
|
||||
/* tabview button & menu item */
|
||||
|
||||
#menu_tabview {
|
||||
|
@ -1836,25 +1803,6 @@ toolbarbutton[type="socialmark"] > .toolbarbutton-icon {
|
|||
%ifndef WINDOWS_AERO
|
||||
/* Use lighter colors of buttons and text in the titlebar on luna-blue */
|
||||
@media (-moz-windows-theme: luna-blue) {
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) .tabbrowser-arrowscrollbox > .scrollbutton-up,
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) .tabbrowser-arrowscrollbox > .scrollbutton-down {
|
||||
list-style-image: url(chrome://browser/skin/tabbrowser/tab-arrow-left-inverted.png);
|
||||
}
|
||||
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) .tabs-newtab-button,
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) #TabsToolbar > #new-tab-button,
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) #TabsToolbar > toolbarpaletteitem > #new-tab-button {
|
||||
list-style-image: url(chrome://browser/skin/tabbrowser/newtab-inverted.png);
|
||||
}
|
||||
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) #alltabs-button {
|
||||
list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png");
|
||||
}
|
||||
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) .tab-close-button:not(:-moz-any(:hover,:-moz-lwtheme,[selected="true"])) {
|
||||
-moz-image-region: rect(0, 64px, 16px, 48px);
|
||||
}
|
||||
|
||||
#tabbrowser-tabs[movingtab] > .tabbrowser-tab[beforeselected]:not([last-visible-tab])::after,
|
||||
.tabbrowser-tab:not([selected]):not([afterselected-visible]):not([afterhovered]):not([first-visible-tab]):not(:hover)::before,
|
||||
#tabbrowser-tabs:not([overflow]) > .tabbrowser-tab[last-visible-tab]:not([selected]):not([beforehovered]):not(:hover)::after {
|
||||
|
@ -1863,7 +1811,7 @@ toolbarbutton[type="socialmark"] > .toolbarbutton-icon {
|
|||
}
|
||||
%endif
|
||||
|
||||
.tab-close-button:not(:hover):not([selected="true"]):-moz-lwtheme-brighttext {
|
||||
#TabsToolbar[brighttext] .tab-close-button:not(:hover):not([selected="true"]) {
|
||||
-moz-image-region: rect(0, 64px, 16px, 48px) !important;
|
||||
}
|
||||
|
||||
|
@ -1906,10 +1854,8 @@ toolbarbutton[type="socialmark"] > .toolbarbutton-icon {
|
|||
background-origin: border-box;
|
||||
}
|
||||
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) .tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-system-metric(windows-classic):not(:-moz-lwtheme),
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) .tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-system-metric(windows-classic):not(:-moz-lwtheme),
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-lwtheme-brighttext,
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-lwtheme-brighttext {
|
||||
#TabsToolbar[brighttext] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .scrollbutton-up,
|
||||
#TabsToolbar[brighttext] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .scrollbutton-down {
|
||||
list-style-image: url(chrome://browser/skin/tabbrowser/tab-arrow-left-inverted.png);
|
||||
}
|
||||
|
||||
|
@ -1951,12 +1897,9 @@ toolbarbutton[type="socialmark"] > .toolbarbutton-icon {
|
|||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) .tabs-newtab-button:-moz-system-metric(windows-classic):not(:-moz-lwtheme),
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) #TabsToolbar > #new-tab-button:-moz-system-metric(windows-classic):not(:-moz-lwtheme),
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) #TabsToolbar > toolbarpaletteitem > #new-tab-button:-moz-system-metric(windows-classic):not(:-moz-lwtheme),
|
||||
.tabs-newtab-button:-moz-lwtheme-brighttext,
|
||||
#TabsToolbar > #new-tab-button:-moz-lwtheme-brighttext,
|
||||
#TabsToolbar > toolbarpaletteitem > #new-tab-button:-moz-lwtheme-brighttext {
|
||||
#TabsToolbar[brighttext] .tabs-newtab-button,
|
||||
#TabsToolbar[brighttext] > #new-tab-button,
|
||||
#TabsToolbar[brighttext] > toolbarpaletteitem > #new-tab-button {
|
||||
list-style-image: url(chrome://browser/skin/tabbrowser/newtab-inverted.png);
|
||||
}
|
||||
|
||||
|
@ -1968,8 +1911,8 @@ toolbarbutton[type="socialmark"] > .toolbarbutton-icon {
|
|||
list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow.png");
|
||||
}
|
||||
|
||||
#main-window[tabsintitlebar]:not([inFullscreen]) #alltabs-button:-moz-system-metric(windows-classic):not(:-moz-lwtheme),
|
||||
#alltabs-button:-moz-lwtheme-brighttext {
|
||||
#TabsToolbar[brighttext] > #alltabs-button,
|
||||
#TabsToolbar[brighttext] > toolbarpaletteitem > #alltabs-button {
|
||||
list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png");
|
||||
}
|
||||
|
||||
|
@ -2620,7 +2563,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
|
|||
list-style-image: url(chrome://browser/skin/Metro_Glyph.png);
|
||||
}
|
||||
|
||||
#switch-to-metro-button[cui-areatype="toolbar"]:-moz-lwtheme-brighttext {
|
||||
toolbar[brighttext] #switch-to-metro-button[cui-areatype="toolbar"] {
|
||||
list-style-image: url(chrome://browser/skin/Metro_Glyph-inverted.png);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,191 +0,0 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* 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/. */
|
||||
|
||||
/* Take away these two :visited rules to get a core dumper */
|
||||
/* See https://bugzilla.mozilla.org/show_bug.cgi?id=575675#c30 */
|
||||
.link,
|
||||
.link:visited {
|
||||
color: #0091ff;
|
||||
}
|
||||
.link,
|
||||
.helplink,
|
||||
.link:visited,
|
||||
.helplink:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
.link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* From content */
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:root {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display : flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#propertyContainer {
|
||||
-moz-user-select: text;
|
||||
overflow: auto;
|
||||
min-height: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.property-view-hidden,
|
||||
.property-content-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.property-view {
|
||||
clear: both;
|
||||
padding: 2px 0 2px 17px;
|
||||
}
|
||||
|
||||
.property-view > * {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.property-name {
|
||||
/* -12px is so the expander triangle isn't pushed up above the property */
|
||||
width: calc(100% - 12px);
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.property-value {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
background-image: url(arrow-e.png);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 5px 8px;
|
||||
background-position: 2px center;
|
||||
padding-left: 10px;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.other-property-value {
|
||||
background-image: url(arrow-e.png);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 5px 8px;
|
||||
background-position: left center;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
@media (min-width: 400px) {
|
||||
.property-name {
|
||||
width: 200px;
|
||||
}
|
||||
.property-value {
|
||||
/* -212px is accounting for the 200px property-name and the 12px triangle */
|
||||
width: calc(100% - 212px);
|
||||
}
|
||||
}
|
||||
|
||||
.property-content {
|
||||
padding-left: 17px;
|
||||
}
|
||||
|
||||
/* From skin */
|
||||
.expander {
|
||||
visibility: hidden;
|
||||
margin-left: -12px!important;
|
||||
}
|
||||
|
||||
.expandable {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.match {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.matchedselectors > p {
|
||||
clear: both;
|
||||
margin: 0 2px 0 0;
|
||||
padding: 2px;
|
||||
overflow-x: hidden;
|
||||
border-style: dotted;
|
||||
border-color: rgba(128,128,128,0.4);
|
||||
border-width: 1px 1px 0 1px;
|
||||
}
|
||||
|
||||
.matchedselectors > p:last-of-type {
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
/* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
|
||||
.rule-text {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.matched {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.parentmatch {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#noResults {
|
||||
font-size: 110%;
|
||||
margin: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.onlyuserstyles {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.legendKey {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.devtools-toolbar {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.link {
|
||||
padding: 0 3px;
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.computedview-colorswatch {
|
||||
border-radius: 50%;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: text-top;
|
||||
-moz-margin-end: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.computedview-colorswatch::before {
|
||||
content: '';
|
||||
background-color: #eee;
|
||||
background-image: linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc),
|
||||
linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc);
|
||||
background-size: 12px 12px;
|
||||
background-position: 0 0, 6px 6px;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
z-index: -1;
|
||||
}
|
|
@ -2,28 +2,7 @@
|
|||
* 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/. */
|
||||
|
||||
@media (-moz-windows-glass) {
|
||||
/* The following rules are for the downloads indicator when in its normal,
|
||||
non-downloading, non-paused state (ie, it's just showing the downloads
|
||||
button icon). */
|
||||
#toolbar-menubar #downloads-button:not([attention]) > #downloads-indicator-anchor > #downloads-indicator-icon:not(:-moz-lwtheme),
|
||||
|
||||
/* The following rules are for the downloads indicator when in its paused
|
||||
or undetermined progress state. We use :not([counter]) as a shortcut for
|
||||
:-moz-any([progress], [paused]). */
|
||||
|
||||
/* This is the case where the downloads indicator has been moved next to the menubar. */
|
||||
#toolbar-menubar #downloads-button:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
|
||||
background-image: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"), 0, 198, 18, 180);
|
||||
}
|
||||
|
||||
#toolbar-menubar #downloads-indicator-counter:not(:-moz-lwtheme) {
|
||||
color: white;
|
||||
text-shadow: 0 0 1px rgba(0,0,0,.7),
|
||||
0 1px 1.5px rgba(0,0,0,.5);
|
||||
}
|
||||
}
|
||||
|
||||
#downloads-indicator-counter {
|
||||
/* Bug 812345 added this... */
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
min-height: 18px;
|
||||
}
|
||||
|
||||
#downloads-indicator-icon:-moz-lwtheme-brighttext {
|
||||
toolbar[brighttext] #downloads-button:not([attention]) > #downloads-indicator-anchor > #downloads-indicator-icon {
|
||||
background: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"),
|
||||
0, 198, 18, 180) center no-repeat;
|
||||
}
|
||||
|
@ -64,8 +64,7 @@
|
|||
background-size: 12px;
|
||||
}
|
||||
|
||||
#downloads-button:not([counter]) > #downloads-indicator-anchor >
|
||||
#downloads-button-progress-area > #downloads-indicator-counter:-moz-lwtheme-brighttext {
|
||||
toolbar[brighttext] #downloads-button:not([counter]):not([attention]) > #downloads-indicator-anchor > #downloads-button-progress-area > #downloads-indicator-counter {
|
||||
background-image: -moz-image-rect(url("chrome://browser/skin/Toolbar-inverted.png"), 0, 198, 18, 180);
|
||||
}
|
||||
|
||||
|
@ -130,7 +129,7 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
#downloads-indicator-counter:-moz-lwtheme-brighttext {
|
||||
toolbar[brighttext] #downloads-indicator-counter {
|
||||
color: white;
|
||||
text-shadow: 0 0 1px rgba(0,0,0,.7),
|
||||
0 1px 1.5px rgba(0,0,0,.5);
|
||||
|
|
|
@ -275,8 +275,8 @@ browser.jar:
|
|||
skin/classic/browser/devtools/magnifying-glass-light@2x.png (../shared/devtools/images/magnifying-glass-light@2x.png)
|
||||
skin/classic/browser/devtools/itemToggle.png (../shared/devtools/images/itemToggle.png)
|
||||
skin/classic/browser/devtools/itemToggle-light.png (../shared/devtools/images/itemToggle-light.png)
|
||||
skin/classic/browser/devtools/itemArrow-dark-rtl.png (../shared/devtools/images/itemArrow-dark-rtl.png)
|
||||
skin/classic/browser/devtools/itemArrow-dark-ltr.png (../shared/devtools/images/itemArrow-dark-ltr.png)
|
||||
skin/classic/browser/devtools/itemArrow-dark-rtl.svg (../shared/devtools/images/itemArrow-dark-rtl.svg)
|
||||
skin/classic/browser/devtools/itemArrow-dark-ltr.svg (../shared/devtools/images/itemArrow-dark-ltr.svg)
|
||||
skin/classic/browser/devtools/itemArrow-rtl.svg (../shared/devtools/images/itemArrow-rtl.svg)
|
||||
skin/classic/browser/devtools/itemArrow-ltr.svg (../shared/devtools/images/itemArrow-ltr.svg)
|
||||
skin/classic/browser/devtools/background-noise-toolbar.png (../shared/devtools/images/background-noise-toolbar.png)
|
||||
|
@ -338,7 +338,7 @@ browser.jar:
|
|||
skin/classic/browser/devtools/vview-open-inspector@2x.png (../shared/devtools/images/vview-open-inspector@2x.png)
|
||||
skin/classic/browser/devtools/undock@2x.png (../shared/devtools/images/undock@2x.png)
|
||||
skin/classic/browser/devtools/font-inspector.css (../shared/devtools/font-inspector.css)
|
||||
skin/classic/browser/devtools/computedview.css (devtools/computedview.css)
|
||||
skin/classic/browser/devtools/computedview.css (../shared/devtools/computedview.css)
|
||||
skin/classic/browser/devtools/arrow-e.png (../shared/devtools/images/arrow-e.png)
|
||||
skin/classic/browser/devtools/responsiveui-rotate.png (../shared/devtools/responsiveui-rotate.png)
|
||||
skin/classic/browser/devtools/responsiveui-touch.png (../shared/devtools/responsiveui-touch.png)
|
||||
|
@ -661,8 +661,8 @@ browser.jar:
|
|||
skin/classic/aero/browser/devtools/magnifying-glass-light@2x.png (../shared/devtools/images/magnifying-glass-light@2x.png)
|
||||
skin/classic/aero/browser/devtools/itemToggle.png (../shared/devtools/images/itemToggle.png)
|
||||
skin/classic/aero/browser/devtools/itemToggle-light.png (../shared/devtools/images/itemToggle-light.png)
|
||||
skin/classic/aero/browser/devtools/itemArrow-dark-rtl.png (../shared/devtools/images/itemArrow-dark-rtl.png)
|
||||
skin/classic/aero/browser/devtools/itemArrow-dark-ltr.png (../shared/devtools/images/itemArrow-dark-ltr.png)
|
||||
skin/classic/aero/browser/devtools/itemArrow-dark-rtl.svg (../shared/devtools/images/itemArrow-dark-rtl.svg)
|
||||
skin/classic/aero/browser/devtools/itemArrow-dark-ltr.svg (../shared/devtools/images/itemArrow-dark-ltr.svg)
|
||||
skin/classic/aero/browser/devtools/itemArrow-rtl.svg (../shared/devtools/images/itemArrow-rtl.svg)
|
||||
skin/classic/aero/browser/devtools/itemArrow-ltr.svg (../shared/devtools/images/itemArrow-ltr.svg)
|
||||
skin/classic/aero/browser/devtools/background-noise-toolbar.png (../shared/devtools/images/background-noise-toolbar.png)
|
||||
|
@ -724,7 +724,7 @@ browser.jar:
|
|||
skin/classic/aero/browser/devtools/vview-open-inspector@2x.png (../shared/devtools/images/vview-open-inspector@2x.png)
|
||||
skin/classic/aero/browser/devtools/undock@2x.png (../shared/devtools/images/undock@2x.png)
|
||||
skin/classic/aero/browser/devtools/font-inspector.css (../shared/devtools/font-inspector.css)
|
||||
skin/classic/aero/browser/devtools/computedview.css (devtools/computedview.css)
|
||||
skin/classic/aero/browser/devtools/computedview.css (../shared/devtools/computedview.css)
|
||||
skin/classic/aero/browser/devtools/arrow-e.png (../shared/devtools/images/arrow-e.png)
|
||||
skin/classic/aero/browser/devtools/responsiveui-rotate.png (../shared/devtools/responsiveui-rotate.png)
|
||||
skin/classic/aero/browser/devtools/responsiveui-touch.png (../shared/devtools/responsiveui-touch.png)
|
||||
|
|
|
@ -2163,7 +2163,7 @@ ia64*-hpux*)
|
|||
LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib secur32.lib netapi32.lib"
|
||||
MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV'
|
||||
WARNINGS_AS_ERRORS='-WX'
|
||||
MOZ_OPTIMIZE_FLAGS='-O1'
|
||||
MOZ_OPTIMIZE_FLAGS='-O1 -Oi'
|
||||
MOZ_FIX_LINK_PATHS=
|
||||
MOZ_COMPONENT_NSPR_LIBS='$(NSPR_LIBS)'
|
||||
LDFLAGS="$LDFLAGS -LARGEADDRESSAWARE -NXCOMPAT"
|
||||
|
|
|
@ -639,9 +639,11 @@ ContentSecurityPolicy.prototype = {
|
|||
}
|
||||
var violationMessage = null;
|
||||
if (blockedUri["asciiSpec"]) {
|
||||
violationMessage = CSPLocalizer.getFormatStr("CSPViolationWithURI", [violatedDirective, blockedUri.asciiSpec]);
|
||||
let localizeString = policy._reportOnlyMode ? "CSPROViolationWithURI" : "CSPViolationWithURI";
|
||||
violationMessage = CSPLocalizer.getFormatStr(localizeString, [violatedDirective, blockedUri.asciiSpec]);
|
||||
} else {
|
||||
violationMessage = CSPLocalizer.getFormatStr("CSPViolation", [violatedDirective]);
|
||||
let localizeString = policy._reportOnlyMode ? "CSPROViolation" : "CSPViolation";
|
||||
violationMessage = CSPLocalizer.getFormatStr(localizeString, [violatedDirective]);
|
||||
}
|
||||
policy.log(WARN_FLAG, violationMessage,
|
||||
(aSourceFile) ? aSourceFile : null,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "mozilla/EventStates.h"
|
||||
#include "mozilla/dom/HTMLFormControlsCollection.h"
|
||||
#include "mozilla/dom/HTMLFormElementBinding.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
|
@ -1511,7 +1512,7 @@ HTMLFormElement::FlushPendingSubmission()
|
|||
if (mPendingSubmission) {
|
||||
// Transfer owning reference so that the submissioin doesn't get deleted
|
||||
// if we reenter
|
||||
nsAutoPtr<nsFormSubmission> submission = mPendingSubmission;
|
||||
nsAutoPtr<nsFormSubmission> submission = Move(mPendingSubmission);
|
||||
|
||||
SubmitSubmission(submission);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ LoadManager* LoadManagerBuild(void)
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
#if defined(ANDROID) || defined(LINUX)
|
||||
int loadMeasurementInterval =
|
||||
mozilla::Preferences::GetInt("media.navigator.load_adapt.measure_interval", 1000);
|
||||
int averagingSeconds =
|
||||
|
@ -29,10 +28,6 @@ LoadManager* LoadManagerBuild(void)
|
|||
averagingSeconds,
|
||||
highLoadThreshold,
|
||||
lowLoadThreshold);
|
||||
#else
|
||||
// LoadManager not implemented on this platform.
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void LoadManagerDestroy(mozilla::LoadManager* aLoadManager)
|
||||
|
|
|
@ -29,6 +29,19 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include <sys/time.h>
|
||||
#include <mach/mach_host.h>
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/host_info.h>
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include <pdh.h>
|
||||
#include <tchar.h>
|
||||
#pragma comment(lib, "pdh.lib")
|
||||
#endif
|
||||
|
||||
// NSPR_LOG_MODULES=LoadManager:5
|
||||
#undef LOG
|
||||
#undef LOG_ENABLED
|
||||
|
@ -141,6 +154,109 @@ void LoadMonitor::Shutdown()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
static LPCTSTR TotalCounterPath = _T("\\Processor(_Total)\\% Processor Time");
|
||||
|
||||
class WinProcMon
|
||||
{
|
||||
public:
|
||||
WinProcMon():
|
||||
mQuery(0), mCounter(0) {};
|
||||
~WinProcMon();
|
||||
nsresult Init();
|
||||
nsresult QuerySystemLoad(float* load_percent);
|
||||
static const uint64_t TicksPerSec = 10000000; //100nsec tick (10MHz)
|
||||
private:
|
||||
PDH_HQUERY mQuery;
|
||||
PDH_HCOUNTER mCounter;
|
||||
};
|
||||
|
||||
WinProcMon::~WinProcMon()
|
||||
{
|
||||
if (mQuery != 0) {
|
||||
PdhCloseQuery(mQuery);
|
||||
mQuery = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
WinProcMon::Init()
|
||||
{
|
||||
PDH_HQUERY query;
|
||||
PDH_HCOUNTER counter;
|
||||
|
||||
// Get a query handle to the Performance Data Helper
|
||||
PDH_STATUS status = PdhOpenQuery(
|
||||
NULL, // No log file name: use real-time source
|
||||
0, // zero out user data token: unsued
|
||||
&query);
|
||||
|
||||
if (status != ERROR_SUCCESS) {
|
||||
LOG(("PdhOpenQuery error = %X", status));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Add a pre-defined high performance counter to the query.
|
||||
// This one is for the total CPU usage.
|
||||
status = PdhAddCounter(query, TotalCounterPath, 0, &counter);
|
||||
|
||||
if (status != ERROR_SUCCESS) {
|
||||
PdhCloseQuery(query);
|
||||
LOG(("PdhAddCounter (_Total) error = %X", status));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Need to make an initial query call to set up data capture.
|
||||
status = PdhCollectQueryData(query);
|
||||
|
||||
if (status != ERROR_SUCCESS) {
|
||||
PdhCloseQuery(query);
|
||||
LOG(("PdhCollectQueryData (init) error = %X", status));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mQuery = query;
|
||||
mCounter = counter;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult WinProcMon::QuerySystemLoad(float* load_percent)
|
||||
{
|
||||
*load_percent = 0;
|
||||
|
||||
if (mQuery == 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Update all counters associated with this query object.
|
||||
PDH_STATUS status = PdhCollectQueryData(mQuery);
|
||||
|
||||
if (status != ERROR_SUCCESS) {
|
||||
LOG(("PdhCollectQueryData error = %X", status));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
PDH_FMT_COUNTERVALUE counter;
|
||||
// maximum is 100% regardless of CPU core count.
|
||||
status = PdhGetFormattedCounterValue(
|
||||
mCounter,
|
||||
PDH_FMT_DOUBLE,
|
||||
(LPDWORD)NULL,
|
||||
&counter);
|
||||
|
||||
if (ERROR_SUCCESS != status ||
|
||||
// There are multiple success return values.
|
||||
!IsSuccessSeverity(counter.CStatus)) {
|
||||
LOG(("PdhGetFormattedCounterValue error"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// The result is a percent value, reduce to match expected scale.
|
||||
*load_percent = (float)(counter.doubleValue / 100.0f);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
class LoadStats
|
||||
{
|
||||
public:
|
||||
|
@ -160,7 +276,8 @@ class LoadInfo : public mozilla::RefCounted<LoadInfo>
|
|||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_TYPENAME(LoadInfo)
|
||||
LoadInfo(int aLoadUpdateInterval);
|
||||
LoadInfo(): mLoadUpdateInterval(0) {};
|
||||
nsresult Init(int aLoadUpdateInterval);
|
||||
double GetSystemLoad() { return mSystemLoad.GetLoad(); };
|
||||
double GetProcessLoad() { return mProcessLoad.GetLoad(); };
|
||||
nsresult UpdateSystemLoad();
|
||||
|
@ -171,17 +288,29 @@ private:
|
|||
uint64_t current_total_times,
|
||||
uint64_t current_cpu_times,
|
||||
LoadStats* loadStat);
|
||||
#ifdef XP_WIN
|
||||
WinProcMon mSysMon;
|
||||
HANDLE mProcHandle;
|
||||
int mNumProcessors;
|
||||
#endif
|
||||
LoadStats mSystemLoad;
|
||||
LoadStats mProcessLoad;
|
||||
uint64_t mTicksPerInterval;
|
||||
int mLoadUpdateInterval;
|
||||
};
|
||||
|
||||
LoadInfo::LoadInfo(int aLoadUpdateInterval)
|
||||
: mLoadUpdateInterval(aLoadUpdateInterval)
|
||||
nsresult LoadInfo::Init(int aLoadUpdateInterval)
|
||||
{
|
||||
#if defined(ANDROID) || defined(LINUX)
|
||||
mLoadUpdateInterval = aLoadUpdateInterval;
|
||||
#ifdef XP_WIN
|
||||
mTicksPerInterval = (WinProcMon::TicksPerSec /*Hz*/
|
||||
* mLoadUpdateInterval /*msec*/) / 1000 ;
|
||||
mNumProcessors = PR_GetNumberOfProcessors();
|
||||
mProcHandle = GetCurrentProcess();
|
||||
return mSysMon.Init();
|
||||
#else
|
||||
mTicksPerInterval = (sysconf(_SC_CLK_TCK) * mLoadUpdateInterval) / 1000;
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -189,10 +318,9 @@ void LoadInfo::UpdateCpuLoad(uint64_t ticks_per_interval,
|
|||
uint64_t current_total_times,
|
||||
uint64_t current_cpu_times,
|
||||
LoadStats *loadStat) {
|
||||
|
||||
// Check if we get an inconsistent number of ticks.
|
||||
if (((current_total_times - loadStat->mPrevTotalTimes)
|
||||
> (ticks_per_interval * 10))
|
||||
> (ticks_per_interval * 10))
|
||||
|| current_total_times < loadStat->mPrevTotalTimes
|
||||
|| current_cpu_times < loadStat->mPrevCpuTimes) {
|
||||
// Bug at least on the Nexus 4 and Galaxy S4
|
||||
|
@ -210,7 +338,11 @@ void LoadInfo::UpdateCpuLoad(uint64_t ticks_per_interval,
|
|||
const uint64_t cpu_diff = current_cpu_times - loadStat->mPrevCpuTimes;
|
||||
const uint64_t total_diff = current_total_times - loadStat->mPrevTotalTimes;
|
||||
if (total_diff > 0) {
|
||||
#ifdef XP_WIN
|
||||
float result = (float)cpu_diff / (float)total_diff/ (float)mNumProcessors;
|
||||
#else
|
||||
float result = (float)cpu_diff / (float)total_diff;
|
||||
#endif
|
||||
loadStat->mPrevLoad = result;
|
||||
}
|
||||
loadStat->mPrevTotalTimes = current_total_times;
|
||||
|
@ -254,6 +386,36 @@ nsresult LoadInfo::UpdateSystemLoad()
|
|||
cpu_times,
|
||||
&mSystemLoad);
|
||||
return NS_OK;
|
||||
#elif defined(XP_MACOSX)
|
||||
mach_msg_type_number_t info_cnt = HOST_CPU_LOAD_INFO_COUNT;
|
||||
host_cpu_load_info_data_t load_info;
|
||||
kern_return_t rv = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO,
|
||||
(host_info_t)(&load_info), &info_cnt);
|
||||
|
||||
if (rv != KERN_SUCCESS || info_cnt != HOST_CPU_LOAD_INFO_COUNT) {
|
||||
LOG(("Error from mach/host_statistics call"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const uint64_t cpu_times = load_info.cpu_ticks[CPU_STATE_NICE]
|
||||
+ load_info.cpu_ticks[CPU_STATE_SYSTEM]
|
||||
+ load_info.cpu_ticks[CPU_STATE_USER];
|
||||
const uint64_t total_times = cpu_times + load_info.cpu_ticks[CPU_STATE_IDLE];
|
||||
|
||||
UpdateCpuLoad(mTicksPerInterval,
|
||||
total_times,
|
||||
cpu_times,
|
||||
&mSystemLoad);
|
||||
return NS_OK;
|
||||
#elif defined(XP_WIN)
|
||||
float load;
|
||||
nsresult rv = mSysMon.QuerySystemLoad(&load);
|
||||
|
||||
if (rv == NS_OK) {
|
||||
mSystemLoad.mPrevLoad = load;
|
||||
}
|
||||
|
||||
return rv;
|
||||
#else
|
||||
// Not implemented
|
||||
return NS_OK;
|
||||
|
@ -261,7 +423,7 @@ nsresult LoadInfo::UpdateSystemLoad()
|
|||
}
|
||||
|
||||
nsresult LoadInfo::UpdateProcessLoad() {
|
||||
#if defined(LINUX) || defined(ANDROID)
|
||||
#if defined(LINUX) || defined(ANDROID) || defined(XP_MACOSX)
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
const uint64_t total_times = tv.tv_sec * PR_USEC_PER_SEC + tv.tv_usec;
|
||||
|
@ -280,7 +442,29 @@ nsresult LoadInfo::UpdateProcessLoad() {
|
|||
total_times,
|
||||
cpu_times,
|
||||
&mProcessLoad);
|
||||
#endif // defined(LINUX) || defined(ANDROID)
|
||||
#elif defined(XP_WIN)
|
||||
FILETIME clk_time, sys_time, user_time;
|
||||
uint64_t total_times, cpu_times;
|
||||
|
||||
GetSystemTimeAsFileTime(&clk_time);
|
||||
total_times = (((uint64_t)clk_time.dwHighDateTime) << 32)
|
||||
+ (uint64_t)clk_time.dwLowDateTime;
|
||||
BOOL ok = GetProcessTimes(mProcHandle, &clk_time, &clk_time, &sys_time, &user_time);
|
||||
|
||||
if (ok == 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
cpu_times = (((uint64_t)sys_time.dwHighDateTime
|
||||
+ (uint64_t)user_time.dwHighDateTime) << 32)
|
||||
+ (uint64_t)sys_time.dwLowDateTime
|
||||
+ (uint64_t)user_time.dwLowDateTime;
|
||||
|
||||
UpdateCpuLoad(mTicksPerInterval,
|
||||
total_times,
|
||||
cpu_times,
|
||||
&mProcessLoad);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -288,12 +472,12 @@ class LoadInfoCollectRunner : public nsRunnable
|
|||
{
|
||||
public:
|
||||
LoadInfoCollectRunner(nsRefPtr<LoadMonitor> loadMonitor,
|
||||
int aLoadUpdateInterval)
|
||||
: mLoadUpdateInterval(aLoadUpdateInterval),
|
||||
RefPtr<LoadInfo> loadInfo)
|
||||
: mLoadUpdateInterval(loadMonitor->mLoadUpdateInterval),
|
||||
mLoadNoiseCounter(0)
|
||||
{
|
||||
mLoadMonitor = loadMonitor;
|
||||
mLoadInfo = new LoadInfo(mLoadUpdateInterval);
|
||||
mLoadInfo = loadInfo;
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
|
@ -304,6 +488,7 @@ public:
|
|||
mLoadInfo->UpdateProcessLoad();
|
||||
float sysLoad = mLoadInfo->GetSystemLoad();
|
||||
float procLoad = mLoadInfo->GetProcessLoad();
|
||||
|
||||
if ((++mLoadNoiseCounter % (LOG_MANY_ENABLED() ? 1 : 10)) == 0) {
|
||||
LOG(("System Load: %f Process Load: %f", sysLoad, procLoad));
|
||||
mLoadNoiseCounter = 0;
|
||||
|
@ -362,16 +547,22 @@ LoadMonitor::Init(nsRefPtr<LoadMonitor> &self)
|
|||
{
|
||||
LOG(("Initializing LoadMonitor"));
|
||||
|
||||
#if defined(ANDROID) || defined(LINUX)
|
||||
RefPtr<LoadInfo> load_info = new LoadInfo();
|
||||
nsresult rv = load_info->Init(mLoadUpdateInterval);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("LoadInfo::Init error"));
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsRefPtr<LoadMonitorAddObserver> addObsRunner = new LoadMonitorAddObserver(self);
|
||||
NS_DispatchToMainThread(addObsRunner, NS_DISPATCH_NORMAL);
|
||||
|
||||
NS_NewNamedThread("Sys Load Info", getter_AddRefs(mLoadInfoThread));
|
||||
|
||||
nsRefPtr<LoadInfoCollectRunner> runner =
|
||||
new LoadInfoCollectRunner(self, mLoadUpdateInterval);
|
||||
new LoadInfoCollectRunner(self, load_info);
|
||||
mLoadInfoThread->Dispatch(runner, NS_DISPATCH_NORMAL);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -19,16 +19,13 @@ if CONFIG['MOZ_WEBRTC']:
|
|||
'LoadMonitor.h',
|
||||
'MediaEngineWebRTC.h']
|
||||
UNIFIED_SOURCES += [
|
||||
'LoadManager.cpp',
|
||||
'LoadManagerFactory.cpp',
|
||||
'LoadMonitor.cpp',
|
||||
'MediaEngineTabVideoSource.cpp',
|
||||
'MediaEngineWebRTCAudio.cpp',
|
||||
'MediaEngineWebRTCVideo.cpp',
|
||||
]
|
||||
if CONFIG['OS_ARCH'] == 'Android' or CONFIG['OS_ARCH'] == 'Linux':
|
||||
UNIFIED_SOURCES += [
|
||||
'LoadManager.cpp',
|
||||
'LoadMonitor.cpp',
|
||||
]
|
||||
# MediaEngineWebRTC.cpp needs to be built separately.
|
||||
SOURCES += [
|
||||
'MediaEngineWebRTC.cpp',
|
||||
|
|
|
@ -32,7 +32,7 @@ let WindowMap = {
|
|||
if (!this._map || !win) {
|
||||
return false;
|
||||
}
|
||||
return this._map.get(win, false);
|
||||
return this._map.get(win) || false;
|
||||
},
|
||||
|
||||
/*
|
||||
|
|
|
@ -10,6 +10,13 @@ CSPViolation = The page's settings blocked the loading of a resource: %1$S
|
|||
# %1$S is the directive that has been violated.
|
||||
# %2$S is the URI of the resource which violated the directive.
|
||||
CSPViolationWithURI = The page's settings blocked the loading of a resource at %2$S ("%1$S").
|
||||
# LOCALIZATION NOTE (CSPROViolation):
|
||||
# %1$S is the reason why the resource has not been loaded.
|
||||
CSPROViolation = A violation occurred for a report-only CSP policy ("%1$S"). The behavior was allowed, and a CSP report was sent.
|
||||
# LOCALIZATION NOTE (CSPROViolationWithURI):
|
||||
# %1$S is the directive that has been violated.
|
||||
# %2$S is the URI of the resource which violated the directive.
|
||||
CSPROViolationWithURI = The page's settings observed the loading of a resource at %2$S ("%1$S"). A CSP report is being sent.
|
||||
# LOCALIZATION NOTE (triedToSendReport):
|
||||
# %1$S is the URI we attempted to send a report to.
|
||||
triedToSendReport = Tried to send report to invalid URI: "%1$S"
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<body>
|
||||
<script class="testbody" type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestCompleteLog();
|
||||
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
|
||||
|
||||
window.frameLoaded = function frameLoaded_toCrash() {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<body>
|
||||
<script class="testbody" type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.requestCompleteLog();
|
||||
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
|
||||
|
||||
window.frameLoaded = function frameLoaded_toCrash() {
|
||||
|
|
|
@ -29,6 +29,7 @@ nsSMILAnimationController::nsSMILAnimationController(nsIDocument* aDoc)
|
|||
mResampleNeeded(false),
|
||||
mDeferredStartSampling(false),
|
||||
mRunningSample(false),
|
||||
mRegisteredWithRefreshDriver(false),
|
||||
mDocument(aDoc)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aDoc, "need a non-null document");
|
||||
|
@ -49,6 +50,8 @@ nsSMILAnimationController::~nsSMILAnimationController()
|
|||
NS_ASSERTION(mAnimationElementTable.Count() == 0,
|
||||
"Animation controller shouldn't be tracking any animation"
|
||||
" elements when it dies");
|
||||
NS_ASSERTION(!mRegisteredWithRefreshDriver,
|
||||
"Leaving stale entry in refresh driver's observer list");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -90,8 +93,8 @@ nsSMILAnimationController::Resume(uint32_t aType)
|
|||
nsSMILTimeContainer::Resume(aType);
|
||||
|
||||
if (wasPaused && !mPauseState && mChildContainerTable.Count()) {
|
||||
Sample(); // Run the first sample manually
|
||||
MaybeStartSampling(GetRefreshDriver());
|
||||
Sample(); // Run the first sample manually
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,6 +263,8 @@ nsSMILAnimationController::StartSampling(nsRefreshDriver* aRefreshDriver)
|
|||
NS_ASSERTION(!mDeferredStartSampling,
|
||||
"Started sampling but the deferred start flag is still set");
|
||||
if (aRefreshDriver) {
|
||||
MOZ_ASSERT(!mRegisteredWithRefreshDriver,
|
||||
"Redundantly registering with refresh driver");
|
||||
NS_ABORT_IF_FALSE(!GetRefreshDriver() ||
|
||||
aRefreshDriver == GetRefreshDriver(),
|
||||
"Starting sampling with wrong refresh driver");
|
||||
|
@ -267,19 +272,21 @@ nsSMILAnimationController::StartSampling(nsRefreshDriver* aRefreshDriver)
|
|||
// or else it will confuse our "average time between samples" calculations.
|
||||
mCurrentSampleTime = mozilla::TimeStamp::Now();
|
||||
aRefreshDriver->AddRefreshObserver(this, Flush_Style);
|
||||
mRegisteredWithRefreshDriver = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSMILAnimationController::StopSampling(nsRefreshDriver* aRefreshDriver)
|
||||
{
|
||||
if (aRefreshDriver) {
|
||||
if (aRefreshDriver && mRegisteredWithRefreshDriver) {
|
||||
// NOTE: The document might already have been detached from its PresContext
|
||||
// (and RefreshDriver), which would make GetRefreshDriverForDoc return null.
|
||||
// (and RefreshDriver), which would make GetRefreshDriver() return null.
|
||||
NS_ABORT_IF_FALSE(!GetRefreshDriver() ||
|
||||
aRefreshDriver == GetRefreshDriver(),
|
||||
"Stopping sampling with wrong refresh driver");
|
||||
aRefreshDriver->RemoveRefreshObserver(this, Flush_Style);
|
||||
mRegisteredWithRefreshDriver = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -214,6 +214,9 @@ protected:
|
|||
bool mDeferredStartSampling;
|
||||
bool mRunningSample;
|
||||
|
||||
// Are we registered with our document's refresh driver?
|
||||
bool mRegisteredWithRefreshDriver;
|
||||
|
||||
// Store raw ptr to mDocument. It owns the controller, so controller
|
||||
// shouldn't outlive it
|
||||
nsIDocument* mDocument;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef NS_SMILCOMPOSITOR_H_
|
||||
#define NS_SMILCOMPOSITOR_H_
|
||||
|
||||
#include "mozilla/Move.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsString.h"
|
||||
#include "nsSMILAnimationFunction.h"
|
||||
|
@ -65,7 +66,7 @@ public:
|
|||
|
||||
// Transfers |aOther|'s mCachedBaseValue to |this|
|
||||
void StealCachedBaseValue(nsSMILCompositor* aOther) {
|
||||
mCachedBaseValue = aOther->mCachedBaseValue;
|
||||
mCachedBaseValue = mozilla::Move(aOther->mCachedBaseValue);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef NS_SMILTIMEDELEMENT_H_
|
||||
#define NS_SMILTIMEDELEMENT_H_
|
||||
|
||||
#include "mozilla/Move.h"
|
||||
#include "nsSMILInterval.h"
|
||||
#include "nsSMILInstanceTime.h"
|
||||
#include "nsSMILMilestone.h"
|
||||
|
@ -524,7 +525,7 @@ protected:
|
|||
{
|
||||
if (mCurrentInterval) {
|
||||
// Transfer ownership to temp var. (This sets mCurrentInterval to null.)
|
||||
nsAutoPtr<nsSMILInterval> interval(mCurrentInterval);
|
||||
nsAutoPtr<nsSMILInterval> interval(mozilla::Move(mCurrentInterval));
|
||||
interval->Unlink();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -193,6 +193,7 @@ let NotificationDB = {
|
|||
this.queueTask("getall", message.data, function(notifications) {
|
||||
returnMessage("Notification:GetAll:Return:OK", {
|
||||
requestID: message.data.requestID,
|
||||
origin: message.data.origin,
|
||||
notifications: notifications
|
||||
});
|
||||
});
|
||||
|
|
|
@ -47,19 +47,24 @@ NotificationStorage.prototype = {
|
|||
tag: tag,
|
||||
icon: icon,
|
||||
alertName: alertName,
|
||||
timestamp: new Date().getTime()
|
||||
timestamp: new Date().getTime(),
|
||||
origin: origin
|
||||
};
|
||||
|
||||
this._notifications[id] = notification;
|
||||
if (tag) {
|
||||
if (!this._byTag[origin]) {
|
||||
this._byTag[origin] = {};
|
||||
}
|
||||
|
||||
// We might have existing notification with this tag,
|
||||
// if so we need to remove it from our cache.
|
||||
if (this._byTag[tag]) {
|
||||
var oldNotification = this._byTag[tag];
|
||||
if (this._byTag[origin][tag]) {
|
||||
var oldNotification = this._byTag[origin][tag];
|
||||
delete this._notifications[oldNotification.id];
|
||||
}
|
||||
|
||||
this._byTag[tag] = notification;
|
||||
this._byTag[origin][tag] = notification;
|
||||
};
|
||||
|
||||
cpmm.sendAsyncMessage("Notification:Save", {
|
||||
|
@ -69,9 +74,9 @@ NotificationStorage.prototype = {
|
|||
},
|
||||
|
||||
get: function(origin, tag, callback) {
|
||||
if (DEBUG) { debug("GET: " + tag); }
|
||||
if (DEBUG) { debug("GET: " + origin + " " + tag); }
|
||||
if (this._cached) {
|
||||
this._fetchFromCache(tag, callback);
|
||||
this._fetchFromCache(origin, tag, callback);
|
||||
} else {
|
||||
this._fetchFromDB(origin, tag, callback);
|
||||
}
|
||||
|
@ -82,7 +87,7 @@ NotificationStorage.prototype = {
|
|||
var notification = this._notifications[id];
|
||||
if (notification) {
|
||||
if (notification.tag) {
|
||||
delete this._byTag[notification.tag];
|
||||
delete this._byTag[origin][notification.tag];
|
||||
}
|
||||
delete this._notifications[id];
|
||||
}
|
||||
|
@ -99,7 +104,7 @@ NotificationStorage.prototype = {
|
|||
var request = this._requests[message.data.requestID];
|
||||
delete this._requests[message.data.requestID];
|
||||
this._populateCache(message.data.notifications);
|
||||
this._fetchFromCache(request.tag, request.callback);
|
||||
this._fetchFromCache(request.origin, request.tag, request.callback);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -122,16 +127,18 @@ NotificationStorage.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
_fetchFromCache: function(tag, callback) {
|
||||
_fetchFromCache: function(origin, tag, callback) {
|
||||
var notifications = [];
|
||||
// If a tag was specified and we have a notification
|
||||
// with this tag, return that. If no tag was specified
|
||||
// simple return all stored notifications.
|
||||
if (tag && this._byTag[tag]) {
|
||||
notifications.push(this._byTag[tag]);
|
||||
if (tag && this._byTag[origin] && this._byTag[origin][tag]) {
|
||||
notifications.push(this._byTag[origin][tag]);
|
||||
} else if (!tag) {
|
||||
for (var id in this._notifications) {
|
||||
notifications.push(this._notifications[id]);
|
||||
if (this._notifications[id].origin === origin) {
|
||||
notifications.push(this._notifications[id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,8 +166,13 @@ NotificationStorage.prototype = {
|
|||
_populateCache: function(notifications) {
|
||||
notifications.forEach(function(notification) {
|
||||
this._notifications[notification.id] = notification;
|
||||
if (notification.tag) {
|
||||
this._byTag[notification.tag] = notification;
|
||||
if (notification.tag && notification.origin) {
|
||||
let tag = notification.tag;
|
||||
let origin = notification.origin;
|
||||
if (!this._byTag[origin]) {
|
||||
this._byTag[origin] = {};
|
||||
}
|
||||
this._byTag[origin][tag] = notification;
|
||||
}
|
||||
}.bind(this));
|
||||
this._cached = true;
|
||||
|
|
|
@ -781,7 +781,9 @@ ScriptExecutorRunnable::PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
|||
NS_IMETHODIMP
|
||||
ScriptExecutorRunnable::Cancel()
|
||||
{
|
||||
ShutdownScriptLoader(mWorkerPrivate->GetJSContext(), mWorkerPrivate, false);
|
||||
if (mLastIndex == mScriptLoader.mLoadInfos.Length() - 1) {
|
||||
ShutdownScriptLoader(mWorkerPrivate->GetJSContext(), mWorkerPrivate, false);
|
||||
}
|
||||
return MainThreadWorkerSyncRunnable::Cancel();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/XPathEvaluator.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsXPathExpression.h"
|
||||
|
@ -129,7 +130,7 @@ XPathEvaluator::CreateExpression(const nsAString & aExpression,
|
|||
|
||||
nsCOMPtr<nsIDOMDocument> document = do_QueryReferent(mDocument);
|
||||
|
||||
*aResult = new nsXPathExpression(expression, mRecycler, document);
|
||||
*aResult = new nsXPathExpression(Move(expression), mRecycler, document);
|
||||
if (!*aResult) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* 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/. */
|
||||
|
||||
#include "mozilla/Move.h"
|
||||
#include "nsXPathExpression.h"
|
||||
#include "txExpr.h"
|
||||
#include "txExprResult.h"
|
||||
|
@ -14,6 +15,8 @@
|
|||
#include "txURIUtils.h"
|
||||
#include "txXPathTreeWalker.h"
|
||||
|
||||
using mozilla::Move;
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(nsXPathExpression, mDocument)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXPathExpression)
|
||||
|
@ -28,10 +31,10 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXPathExpression)
|
|||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XPathExpression)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
nsXPathExpression::nsXPathExpression(nsAutoPtr<Expr>& aExpression,
|
||||
nsXPathExpression::nsXPathExpression(nsAutoPtr<Expr>&& aExpression,
|
||||
txResultRecycler* aRecycler,
|
||||
nsIDOMDocument *aDocument)
|
||||
: mExpression(aExpression),
|
||||
: mExpression(Move(aExpression)),
|
||||
mRecycler(aRecycler),
|
||||
mDocument(aDocument)
|
||||
{
|
||||
|
|
|
@ -24,7 +24,7 @@ class nsXPathExpression MOZ_FINAL : public nsIDOMXPathExpression,
|
|||
public nsIDOMNSXPathExpression
|
||||
{
|
||||
public:
|
||||
nsXPathExpression(nsAutoPtr<Expr>& aExpression, txResultRecycler* aRecycler,
|
||||
nsXPathExpression(nsAutoPtr<Expr>&& aExpression, txResultRecycler* aRecycler,
|
||||
nsIDOMDocument *aDocument);
|
||||
|
||||
// nsISupports interface
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* @see ExprLexer
|
||||
**/
|
||||
|
||||
#include "mozilla/Move.h"
|
||||
#include "txExprParser.h"
|
||||
#include "txExprLexer.h"
|
||||
#include "txExpr.h"
|
||||
|
@ -20,6 +21,8 @@
|
|||
#include "txXPathNode.h"
|
||||
#include "txXPathOptimizer.h"
|
||||
|
||||
using mozilla::Move;
|
||||
|
||||
/**
|
||||
* Creates an Attribute Value Template using the given value
|
||||
* This should move to XSLProcessor class
|
||||
|
@ -113,7 +116,7 @@ txExprParser::createAVT(const nsSubstring& aAttrValue,
|
|||
|
||||
// Add expression, create a concat() call if necessary
|
||||
if (!expr) {
|
||||
expr = newExpr;
|
||||
expr = Move(newExpr);
|
||||
}
|
||||
else {
|
||||
if (!concat) {
|
||||
|
@ -311,7 +314,7 @@ txExprParser::createExpr(txExprLexer& lexer, txIParseContext* aContext,
|
|||
<= precedence(static_cast<Token*>(ops.peek()))) {
|
||||
// can't use expr as argument due to order of evaluation
|
||||
nsAutoPtr<Expr> left(static_cast<Expr*>(exprs.pop()));
|
||||
nsAutoPtr<Expr> right(expr);
|
||||
nsAutoPtr<Expr> right(Move(expr));
|
||||
rv = createBinaryExpr(left, right,
|
||||
static_cast<Token*>(ops.pop()),
|
||||
getter_Transfers(expr));
|
||||
|
@ -330,7 +333,7 @@ txExprParser::createExpr(txExprLexer& lexer, txIParseContext* aContext,
|
|||
|
||||
while (NS_SUCCEEDED(rv) && !exprs.isEmpty()) {
|
||||
nsAutoPtr<Expr> left(static_cast<Expr*>(exprs.pop()));
|
||||
nsAutoPtr<Expr> right(expr);
|
||||
nsAutoPtr<Expr> right(Move(expr));
|
||||
rv = createBinaryExpr(left, right, static_cast<Token*>(ops.pop()),
|
||||
getter_Transfers(expr));
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* 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/. */
|
||||
|
||||
#include "mozilla/Move.h"
|
||||
#include "txInstructions.h"
|
||||
#include "nsError.h"
|
||||
#include "txExpr.h"
|
||||
|
@ -18,6 +19,8 @@
|
|||
#include "txXSLTNumber.h"
|
||||
#include "txExecutionState.h"
|
||||
|
||||
using mozilla::Move;
|
||||
|
||||
nsresult
|
||||
txApplyDefaultElementTemplate::execute(txExecutionState& aEs)
|
||||
{
|
||||
|
@ -86,11 +89,9 @@ txApplyTemplates::execute(txExecutionState& aEs)
|
|||
return aEs.runTemplate(templ);
|
||||
}
|
||||
|
||||
txAttribute::txAttribute(nsAutoPtr<Expr> aName, nsAutoPtr<Expr> aNamespace,
|
||||
txAttribute::txAttribute(nsAutoPtr<Expr>&& aName, nsAutoPtr<Expr>&& aNamespace,
|
||||
txNamespaceMap* aMappings)
|
||||
: mName(aName),
|
||||
mNamespace(aNamespace),
|
||||
mMappings(aMappings)
|
||||
: mName(Move(aName)), mNamespace(Move(aNamespace)), mMappings(aMappings)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -179,10 +180,9 @@ txCheckParam::execute(txExecutionState& aEs)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
txConditionalGoto::txConditionalGoto(nsAutoPtr<Expr> aCondition,
|
||||
txConditionalGoto::txConditionalGoto(nsAutoPtr<Expr>&& aCondition,
|
||||
txInstruction* aTarget)
|
||||
: mCondition(aCondition),
|
||||
mTarget(aTarget)
|
||||
: mCondition(Move(aCondition)), mTarget(aTarget)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -365,8 +365,8 @@ txCopy::execute(txExecutionState& aEs)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
txCopyOf::txCopyOf(nsAutoPtr<Expr> aSelect)
|
||||
: mSelect(aSelect)
|
||||
txCopyOf::txCopyOf(nsAutoPtr<Expr>&& aSelect)
|
||||
: mSelect(Move(aSelect))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -486,11 +486,11 @@ txLoopNodeSet::execute(txExecutionState& aEs)
|
|||
}
|
||||
|
||||
txLREAttribute::txLREAttribute(int32_t aNamespaceID, nsIAtom* aLocalName,
|
||||
nsIAtom* aPrefix, nsAutoPtr<Expr> aValue)
|
||||
nsIAtom* aPrefix, nsAutoPtr<Expr>&& aValue)
|
||||
: mNamespaceID(aNamespaceID),
|
||||
mLocalName(aLocalName),
|
||||
mPrefix(aPrefix),
|
||||
mValue(aValue)
|
||||
mValue(Move(aValue))
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
mLowercaseLocalName = TX_ToLowerCaseAtom(aLocalName);
|
||||
|
@ -541,13 +541,17 @@ txMessage::execute(txExecutionState& aEs)
|
|||
return mTerminate ? NS_ERROR_XSLT_ABORTED : NS_OK;
|
||||
}
|
||||
|
||||
txNumber::txNumber(txXSLTNumber::LevelType aLevel, nsAutoPtr<txPattern> aCount,
|
||||
nsAutoPtr<txPattern> aFrom, nsAutoPtr<Expr> aValue,
|
||||
nsAutoPtr<Expr> aFormat, nsAutoPtr<Expr> aGroupingSeparator,
|
||||
nsAutoPtr<Expr> aGroupingSize)
|
||||
: mLevel(aLevel), mCount(aCount), mFrom(aFrom), mValue(aValue),
|
||||
mFormat(aFormat), mGroupingSeparator(aGroupingSeparator),
|
||||
mGroupingSize(aGroupingSize)
|
||||
txNumber::txNumber(txXSLTNumber::LevelType aLevel,
|
||||
nsAutoPtr<txPattern>&& aCount, nsAutoPtr<txPattern>&& aFrom,
|
||||
nsAutoPtr<Expr>&& aValue, nsAutoPtr<Expr>&& aFormat,
|
||||
nsAutoPtr<Expr>&& aGroupingSeparator,
|
||||
nsAutoPtr<Expr>&& aGroupingSize)
|
||||
: mLevel(aLevel), mCount(Move(aCount)),
|
||||
mFrom(Move(aFrom)),
|
||||
mValue(Move(aValue)),
|
||||
mFormat(Move(aFormat)),
|
||||
mGroupingSeparator(Move(aGroupingSeparator)),
|
||||
mGroupingSize(Move(aGroupingSize))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -572,8 +576,8 @@ txPopParams::execute(txExecutionState& aEs)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
txProcessingInstruction::txProcessingInstruction(nsAutoPtr<Expr> aName)
|
||||
: mName(aName)
|
||||
txProcessingInstruction::txProcessingInstruction(nsAutoPtr<Expr>&& aName)
|
||||
: mName(Move(aName))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -599,8 +603,8 @@ txProcessingInstruction::execute(txExecutionState& aEs)
|
|||
return aEs.mResultHandler->processingInstruction(name, handler->mValue);
|
||||
}
|
||||
|
||||
txPushNewContext::txPushNewContext(nsAutoPtr<Expr> aSelect)
|
||||
: mSelect(aSelect), mBailTarget(nullptr)
|
||||
txPushNewContext::txPushNewContext(nsAutoPtr<Expr>&& aSelect)
|
||||
: mSelect(Move(aSelect)), mBailTarget(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -660,19 +664,19 @@ txPushNewContext::execute(txExecutionState& aEs)
|
|||
}
|
||||
|
||||
nsresult
|
||||
txPushNewContext::addSort(nsAutoPtr<Expr> aSelectExpr,
|
||||
nsAutoPtr<Expr> aLangExpr,
|
||||
nsAutoPtr<Expr> aDataTypeExpr,
|
||||
nsAutoPtr<Expr> aOrderExpr,
|
||||
nsAutoPtr<Expr> aCaseOrderExpr)
|
||||
txPushNewContext::addSort(nsAutoPtr<Expr>&& aSelectExpr,
|
||||
nsAutoPtr<Expr>&& aLangExpr,
|
||||
nsAutoPtr<Expr>&& aDataTypeExpr,
|
||||
nsAutoPtr<Expr>&& aOrderExpr,
|
||||
nsAutoPtr<Expr>&& aCaseOrderExpr)
|
||||
{
|
||||
if (SortKey *key = mSortKeys.AppendElement()) {
|
||||
// workaround for not triggering the Copy Constructor
|
||||
key->mSelectExpr = aSelectExpr;
|
||||
key->mLangExpr = aLangExpr;
|
||||
key->mDataTypeExpr = aDataTypeExpr;
|
||||
key->mOrderExpr = aOrderExpr;
|
||||
key->mCaseOrderExpr = aCaseOrderExpr;
|
||||
key->mSelectExpr = Move(aSelectExpr);
|
||||
key->mLangExpr = Move(aLangExpr);
|
||||
key->mDataTypeExpr = Move(aDataTypeExpr);
|
||||
key->mOrderExpr = Move(aOrderExpr);
|
||||
key->mCaseOrderExpr = Move(aCaseOrderExpr);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -748,8 +752,8 @@ txReturn::execute(txExecutionState& aEs)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
txSetParam::txSetParam(const txExpandedName& aName, nsAutoPtr<Expr> aValue)
|
||||
: mName(aName), mValue(aValue)
|
||||
txSetParam::txSetParam(const txExpandedName& aName, nsAutoPtr<Expr>&& aValue)
|
||||
: mName(aName), mValue(Move(aValue))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -782,8 +786,8 @@ txSetParam::execute(txExecutionState& aEs)
|
|||
}
|
||||
|
||||
txSetVariable::txSetVariable(const txExpandedName& aName,
|
||||
nsAutoPtr<Expr> aValue)
|
||||
: mName(aName), mValue(aValue)
|
||||
nsAutoPtr<Expr>&& aValue)
|
||||
: mName(aName), mValue(Move(aValue))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -806,11 +810,11 @@ txSetVariable::execute(txExecutionState& aEs)
|
|||
return aEs.bindVariable(mName, exprRes);
|
||||
}
|
||||
|
||||
txStartElement::txStartElement(nsAutoPtr<Expr> aName,
|
||||
nsAutoPtr<Expr> aNamespace,
|
||||
txStartElement::txStartElement(nsAutoPtr<Expr>&& aName,
|
||||
nsAutoPtr<Expr>&& aNamespace,
|
||||
txNamespaceMap* aMappings)
|
||||
: mName(aName),
|
||||
mNamespace(aNamespace),
|
||||
: mName(Move(aName)),
|
||||
mNamespace(Move(aNamespace)),
|
||||
mMappings(aMappings)
|
||||
{
|
||||
}
|
||||
|
@ -916,8 +920,8 @@ txText::execute(txExecutionState& aEs)
|
|||
return aEs.mResultHandler->characters(mStr, mDOE);
|
||||
}
|
||||
|
||||
txValueOf::txValueOf(nsAutoPtr<Expr> aExpr, bool aDOE)
|
||||
: mExpr(aExpr),
|
||||
txValueOf::txValueOf(nsAutoPtr<Expr>&& aExpr, bool aDOE)
|
||||
: mExpr(Move(aExpr)),
|
||||
mDOE(aDOE)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ public:
|
|||
class txAttribute : public txInstruction
|
||||
{
|
||||
public:
|
||||
txAttribute(nsAutoPtr<Expr> aName, nsAutoPtr<Expr> aNamespace,
|
||||
txAttribute(nsAutoPtr<Expr>&& aName, nsAutoPtr<Expr>&& aNamespace,
|
||||
txNamespaceMap* aMappings);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
@ -105,7 +105,7 @@ public:
|
|||
class txConditionalGoto : public txInstruction
|
||||
{
|
||||
public:
|
||||
txConditionalGoto(nsAutoPtr<Expr> aCondition, txInstruction* aTarget);
|
||||
txConditionalGoto(nsAutoPtr<Expr>&& aCondition, txInstruction* aTarget);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
|
@ -138,7 +138,7 @@ public:
|
|||
class txCopyOf : public txCopyBase
|
||||
{
|
||||
public:
|
||||
txCopyOf(nsAutoPtr<Expr> aSelect);
|
||||
txCopyOf(nsAutoPtr<Expr>&& aSelect);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
|
@ -191,7 +191,7 @@ class txLREAttribute : public txInstruction
|
|||
{
|
||||
public:
|
||||
txLREAttribute(int32_t aNamespaceID, nsIAtom* aLocalName,
|
||||
nsIAtom* aPrefix, nsAutoPtr<Expr> aValue);
|
||||
nsIAtom* aPrefix, nsAutoPtr<Expr>&& aValue);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
|
@ -215,10 +215,10 @@ public:
|
|||
class txNumber : public txInstruction
|
||||
{
|
||||
public:
|
||||
txNumber(txXSLTNumber::LevelType aLevel, nsAutoPtr<txPattern> aCount,
|
||||
nsAutoPtr<txPattern> aFrom, nsAutoPtr<Expr> aValue,
|
||||
nsAutoPtr<Expr> aFormat, nsAutoPtr<Expr> aGroupingSeparator,
|
||||
nsAutoPtr<Expr> aGroupingSize);
|
||||
txNumber(txXSLTNumber::LevelType aLevel, nsAutoPtr<txPattern>&& aCount,
|
||||
nsAutoPtr<txPattern>&& aFrom, nsAutoPtr<Expr>&& aValue,
|
||||
nsAutoPtr<Expr>&& aFormat, nsAutoPtr<Expr>&& aGroupingSeparator,
|
||||
nsAutoPtr<Expr>&& aGroupingSize);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
|
@ -240,7 +240,7 @@ public:
|
|||
class txProcessingInstruction : public txInstruction
|
||||
{
|
||||
public:
|
||||
txProcessingInstruction(nsAutoPtr<Expr> aName);
|
||||
txProcessingInstruction(nsAutoPtr<Expr>&& aName);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
|
@ -250,15 +250,17 @@ public:
|
|||
class txPushNewContext : public txInstruction
|
||||
{
|
||||
public:
|
||||
txPushNewContext(nsAutoPtr<Expr> aSelect);
|
||||
txPushNewContext(nsAutoPtr<Expr>&& aSelect);
|
||||
~txPushNewContext();
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
|
||||
nsresult addSort(nsAutoPtr<Expr> aSelectExpr, nsAutoPtr<Expr> aLangExpr,
|
||||
nsAutoPtr<Expr> aDataTypeExpr, nsAutoPtr<Expr> aOrderExpr,
|
||||
nsAutoPtr<Expr> aCaseOrderExpr);
|
||||
nsresult addSort(nsAutoPtr<Expr>&& aSelectExpr,
|
||||
nsAutoPtr<Expr>&& aLangExpr,
|
||||
nsAutoPtr<Expr>&& aDataTypeExpr,
|
||||
nsAutoPtr<Expr>&& aOrderExpr,
|
||||
nsAutoPtr<Expr>&& aCaseOrderExpr);
|
||||
|
||||
struct SortKey {
|
||||
nsAutoPtr<Expr> mSelectExpr;
|
||||
|
@ -320,7 +322,7 @@ public:
|
|||
class txSetParam : public txInstruction
|
||||
{
|
||||
public:
|
||||
txSetParam(const txExpandedName& aName, nsAutoPtr<Expr> aValue);
|
||||
txSetParam(const txExpandedName& aName, nsAutoPtr<Expr>&& aValue);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
|
@ -331,7 +333,7 @@ public:
|
|||
class txSetVariable : public txInstruction
|
||||
{
|
||||
public:
|
||||
txSetVariable(const txExpandedName& aName, nsAutoPtr<Expr> aValue);
|
||||
txSetVariable(const txExpandedName& aName, nsAutoPtr<Expr>&& aValue);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
|
@ -342,7 +344,7 @@ public:
|
|||
class txStartElement : public txInstruction
|
||||
{
|
||||
public:
|
||||
txStartElement(nsAutoPtr<Expr> aName, nsAutoPtr<Expr> aNamespace,
|
||||
txStartElement(nsAutoPtr<Expr>&& aName, nsAutoPtr<Expr>&& aNamespace,
|
||||
txNamespaceMap* aMappings);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
@ -380,7 +382,7 @@ public:
|
|||
class txValueOf : public txInstruction
|
||||
{
|
||||
public:
|
||||
txValueOf(nsAutoPtr<Expr> aExpr, bool aDOE);
|
||||
txValueOf(nsAutoPtr<Expr>&& aExpr, bool aDOE);
|
||||
|
||||
TX_DECL_TXINSTRUCTION
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ public:
|
|||
* @param aUse use-expression
|
||||
* @return false if an error occurred, true otherwise
|
||||
*/
|
||||
bool addKey(nsAutoPtr<txPattern> aMatch, nsAutoPtr<Expr> aUse);
|
||||
bool addKey(nsAutoPtr<txPattern>&& aMatch, nsAutoPtr<Expr>&& aUse);
|
||||
|
||||
/**
|
||||
* Indexes a subtree and adds it to the hash of key values
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "txXSLTPatterns.h"
|
||||
#include "txNamespaceMap.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -251,7 +252,7 @@ txKeyHash::init()
|
|||
* @param aUse use-expression
|
||||
* @return false if an error occurred, true otherwise
|
||||
*/
|
||||
bool txXSLKey::addKey(nsAutoPtr<txPattern> aMatch, nsAutoPtr<Expr> aUse)
|
||||
bool txXSLKey::addKey(nsAutoPtr<txPattern>&& aMatch, nsAutoPtr<Expr>&& aUse)
|
||||
{
|
||||
if (!aMatch || !aUse)
|
||||
return false;
|
||||
|
@ -260,8 +261,8 @@ bool txXSLKey::addKey(nsAutoPtr<txPattern> aMatch, nsAutoPtr<Expr> aUse)
|
|||
if (!key)
|
||||
return false;
|
||||
|
||||
key->matchPattern = aMatch;
|
||||
key->useExpr = aUse;
|
||||
key->matchPattern = Move(aMatch);
|
||||
key->useExpr = Move(aUse);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -4,10 +4,13 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "txRtfHandler.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
txResultTreeFragment::txResultTreeFragment(nsAutoPtr<txResultBuffer>& aBuffer)
|
||||
using mozilla::Move;
|
||||
|
||||
txResultTreeFragment::txResultTreeFragment(nsAutoPtr<txResultBuffer>&& aBuffer)
|
||||
: txAExprResult(nullptr),
|
||||
mBuffer(aBuffer)
|
||||
mBuffer(Move(aBuffer))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -58,7 +61,7 @@ nsresult txResultTreeFragment::flushToHandler(txAXMLEventHandler* aHandler)
|
|||
nsresult
|
||||
txRtfHandler::getAsRTF(txAExprResult** aResult)
|
||||
{
|
||||
*aResult = new txResultTreeFragment(mBuffer);
|
||||
*aResult = new txResultTreeFragment(Move(mBuffer));
|
||||
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
NS_ADDREF(*aResult);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
class txResultTreeFragment : public txAExprResult
|
||||
{
|
||||
public:
|
||||
txResultTreeFragment(nsAutoPtr<txResultBuffer>& aBuffer);
|
||||
txResultTreeFragment(nsAutoPtr<txResultBuffer>&& aBuffer);
|
||||
|
||||
TX_DECL_EXPRRESULT
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
#include "txStylesheet.h"
|
||||
#include "txExpr.h"
|
||||
|
@ -15,6 +16,8 @@
|
|||
#include "txKey.h"
|
||||
#include "txXPathTreeWalker.h"
|
||||
|
||||
using mozilla::Move;
|
||||
|
||||
txStylesheet::txStylesheet()
|
||||
: mRootFrame(nullptr)
|
||||
{
|
||||
|
@ -39,7 +42,7 @@ txStylesheet::init()
|
|||
|
||||
nt.forget();
|
||||
|
||||
txPushNewContext* pushContext = new txPushNewContext(nodeExpr);
|
||||
txPushNewContext* pushContext = new txPushNewContext(Move(nodeExpr));
|
||||
mContainerTemplate->mNext = pushContext;
|
||||
NS_ENSURE_TRUE(pushContext, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
|
@ -68,7 +71,7 @@ txStylesheet::init()
|
|||
|
||||
nt.forget();
|
||||
|
||||
mCharactersTemplate = new txValueOf(nodeExpr, false);
|
||||
mCharactersTemplate = new txValueOf(Move(nodeExpr), false);
|
||||
NS_ENSURE_TRUE(mCharactersTemplate, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
mCharactersTemplate->mNext = new txReturn();
|
||||
|
@ -400,10 +403,10 @@ txStylesheet::addTemplate(txTemplateItem* aTemplate,
|
|||
|
||||
// Add the simple patterns to the list of matchable templates, according
|
||||
// to default priority
|
||||
nsAutoPtr<txPattern> simple = aTemplate->mMatch;
|
||||
nsAutoPtr<txPattern> simple = Move(aTemplate->mMatch);
|
||||
nsAutoPtr<txPattern> unionPattern;
|
||||
if (simple->getType() == txPattern::UNION_PATTERN) {
|
||||
unionPattern = simple;
|
||||
unionPattern = Move(simple);
|
||||
simple = unionPattern->getSubPatternAt(0);
|
||||
unionPattern->setSubPatternAt(0, nullptr);
|
||||
}
|
||||
|
@ -428,7 +431,7 @@ txStylesheet::addTemplate(txTemplateItem* aTemplate,
|
|||
NS_ENSURE_TRUE(nt, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nt->mFirstInstruction = instr;
|
||||
nt->mMatch = simple;
|
||||
nt->mMatch = Move(simple);
|
||||
nt->mPriority = priority;
|
||||
|
||||
if (unionPattern) {
|
||||
|
@ -539,7 +542,8 @@ txStylesheet::addGlobalVariable(txVariableItem* aVariable)
|
|||
return NS_OK;
|
||||
}
|
||||
nsAutoPtr<GlobalVariable> var(
|
||||
new GlobalVariable(aVariable->mValue, aVariable->mFirstInstruction,
|
||||
new GlobalVariable(Move(aVariable->mValue),
|
||||
Move(aVariable->mFirstInstruction),
|
||||
aVariable->mIsParam));
|
||||
NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
|
@ -569,7 +573,7 @@ txStylesheet::addKey(const txExpandedName& aName,
|
|||
return rv;
|
||||
}
|
||||
}
|
||||
if (!xslKey->addKey(aMatch, aUse)) {
|
||||
if (!xslKey->addKey(Move(aMatch), Move(aUse))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -577,7 +581,7 @@ txStylesheet::addKey(const txExpandedName& aName,
|
|||
|
||||
nsresult
|
||||
txStylesheet::addDecimalFormat(const txExpandedName& aName,
|
||||
nsAutoPtr<txDecimalFormat> aFormat)
|
||||
nsAutoPtr<txDecimalFormat>&& aFormat)
|
||||
{
|
||||
txDecimalFormat* existing = mDecimalFormats.get(aName);
|
||||
if (existing) {
|
||||
|
@ -603,9 +607,11 @@ txStylesheet::ImportFrame::~ImportFrame()
|
|||
}
|
||||
}
|
||||
|
||||
txStylesheet::GlobalVariable::GlobalVariable(nsAutoPtr<Expr> aExpr,
|
||||
nsAutoPtr<txInstruction> aFirstInstruction,
|
||||
txStylesheet::GlobalVariable::GlobalVariable(nsAutoPtr<Expr>&& aExpr,
|
||||
nsAutoPtr<txInstruction>&& aInstr,
|
||||
bool aIsParam)
|
||||
: mExpr(aExpr), mFirstInstruction(aFirstInstruction), mIsParam(aIsParam)
|
||||
: mExpr(Move(aExpr)),
|
||||
mFirstInstruction(Move(aInstr)),
|
||||
mIsParam(aIsParam)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ public:
|
|||
* Add a decimal-format to the stylesheet
|
||||
*/
|
||||
nsresult addDecimalFormat(const txExpandedName& aName,
|
||||
nsAutoPtr<txDecimalFormat> aFormat);
|
||||
nsAutoPtr<txDecimalFormat>&& aFormat);
|
||||
|
||||
struct MatchableTemplate {
|
||||
txInstruction* mFirstInstruction;
|
||||
|
@ -96,8 +96,8 @@ public:
|
|||
|
||||
class GlobalVariable : public txObject {
|
||||
public:
|
||||
GlobalVariable(nsAutoPtr<Expr> aExpr,
|
||||
nsAutoPtr<txInstruction> aFirstInstruction,
|
||||
GlobalVariable(nsAutoPtr<Expr>&& aExpr,
|
||||
nsAutoPtr<txInstruction>&& aFirstInstruction,
|
||||
bool aIsParam);
|
||||
|
||||
nsAutoPtr<Expr> mExpr;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
#include "txStylesheetCompiler.h"
|
||||
#include "txStylesheetCompileHandlers.h"
|
||||
|
@ -114,7 +115,7 @@ parseUseAttrSets(txStylesheetAttr* aAttributes,
|
|||
nsAutoPtr<txInstruction> instr(new txInsertAttrSet(name));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -525,7 +526,7 @@ txFnStartLREStylesheet(int32_t aNamespaceID,
|
|||
nsAutoPtr<txPattern> match(new txRootPattern());
|
||||
NS_ENSURE_TRUE(match, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsAutoPtr<txTemplateItem> templ(new txTemplateItem(match, nullExpr,
|
||||
nsAutoPtr<txTemplateItem> templ(new txTemplateItem(Move(match), nullExpr,
|
||||
nullExpr, prio));
|
||||
NS_ENSURE_TRUE(templ, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
|
@ -553,7 +554,7 @@ txFnEndLREStylesheet(txStylesheetCompilerState& aState)
|
|||
nsAutoPtr<txInstruction> instr(new txReturn());
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aState.closeInstructionContainer();
|
||||
|
@ -659,7 +660,7 @@ txFnEndAttributeSet(txStylesheetCompilerState& aState)
|
|||
nsAutoPtr<txInstruction> instr(new txReturn());
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aState.closeInstructionContainer();
|
||||
|
@ -735,7 +736,7 @@ txFnStartDecimalFormat(int32_t aNamespaceID,
|
|||
false, aState, format->mPatternSeparator);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aState.mStylesheet->addDecimalFormat(name, format);
|
||||
rv = aState.mStylesheet->addDecimalFormat(name, Move(format));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return aState.pushHandlerTable(gTxIgnoreHandler);
|
||||
|
@ -847,7 +848,7 @@ txFnStartKey(int32_t aNamespaceID,
|
|||
aState, use);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aState.mStylesheet->addKey(name, match, use);
|
||||
rv = aState.mStylesheet->addKey(name, Move(match), Move(use));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return aState.pushHandlerTable(gTxIgnoreHandler);
|
||||
|
@ -1123,7 +1124,8 @@ txFnStartTemplate(int32_t aNamespaceID,
|
|||
name.isNull(), aState, match);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txTemplateItem> templ(new txTemplateItem(match, name, mode, prio));
|
||||
nsAutoPtr<txTemplateItem> templ(new txTemplateItem(Move(match), name, mode,
|
||||
prio));
|
||||
NS_ENSURE_TRUE(templ, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
aState.openInstructionContainer(templ);
|
||||
|
@ -1143,7 +1145,7 @@ txFnEndTemplate(txStylesheetCompilerState& aState)
|
|||
nsAutoPtr<txInstruction> instr(new txReturn());
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aState.closeInstructionContainer();
|
||||
|
@ -1172,7 +1174,8 @@ txFnStartTopVariable(int32_t aNamespaceID,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txVariableItem> var(
|
||||
new txVariableItem(name, select, aLocalName == nsGkAtoms::param));
|
||||
new txVariableItem(name, Move(select),
|
||||
aLocalName == nsGkAtoms::param));
|
||||
NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
aState.openInstructionContainer(var);
|
||||
|
@ -1217,7 +1220,7 @@ txFnEndTopVariable(txStylesheetCompilerState& aState)
|
|||
nsAutoPtr<txInstruction> instr(new txReturn());
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
|
@ -1276,7 +1279,7 @@ txFnStartLRE(int32_t aNamespaceID,
|
|||
aLocalName, aPrefix));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = parseExcludeResultPrefixes(aAttributes, aAttrCount, kNameSpaceID_XSLT);
|
||||
|
@ -1304,10 +1307,10 @@ txFnStartLRE(int32_t aNamespaceID,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
instr = new txLREAttribute(attr->mNamespaceID, attr->mLocalName,
|
||||
attr->mPrefix, avt);
|
||||
attr->mPrefix, Move(avt));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
|
@ -1320,7 +1323,7 @@ txFnEndLRE(txStylesheetCompilerState& aState)
|
|||
nsAutoPtr<txInstruction> instr(new txEndElement);
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1339,7 +1342,7 @@ txFnText(const nsAString& aStr, txStylesheetCompilerState& aState)
|
|||
nsAutoPtr<txInstruction> instr(new txText(aStr, false));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1364,13 +1367,13 @@ txFnStartApplyImports(int32_t aNamespaceID,
|
|||
nsAutoPtr<txInstruction> instr(new txApplyImportsStart);
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
instr = new txApplyImportsEnd;
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return aState.pushHandlerTable(gTxIgnoreHandler);
|
||||
|
@ -1407,7 +1410,7 @@ txFnStartApplyTemplates(int32_t aNamespaceID,
|
|||
nsAutoPtr<txInstruction> instr(new txPushParams);
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
txExpandedName mode;
|
||||
|
@ -1439,7 +1442,7 @@ txFnStartApplyTemplates(int32_t aNamespaceID,
|
|||
nt.forget();
|
||||
}
|
||||
|
||||
nsAutoPtr<txPushNewContext> pushcontext(new txPushNewContext(select));
|
||||
nsAutoPtr<txPushNewContext> pushcontext( new txPushNewContext(Move(select)));
|
||||
NS_ENSURE_TRUE(pushcontext, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.pushSorter(pushcontext);
|
||||
|
@ -1461,7 +1464,7 @@ txFnEndApplyTemplates(txStylesheetCompilerState& aState)
|
|||
txPushNewContext* pushcontext =
|
||||
static_cast<txPushNewContext*>(aState.popObject());
|
||||
nsAutoPtr<txInstruction> instr(pushcontext); // txPushNewContext
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aState.popSorter();
|
||||
|
@ -1470,18 +1473,18 @@ txFnEndApplyTemplates(txStylesheetCompilerState& aState)
|
|||
nsAutoPtr<txLoopNodeSet> loop(new txLoopNodeSet(instr));
|
||||
NS_ENSURE_TRUE(loop, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
instr = loop.forget();
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
instr = new txPopParams;
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
pushcontext->mBailTarget = instr;
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1507,7 +1510,7 @@ txFnStartAttribute(int32_t aNamespaceID,
|
|||
nsAutoPtr<txInstruction> instr(new txPushStringHandler(true));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<Expr> name;
|
||||
|
@ -1520,7 +1523,8 @@ txFnStartAttribute(int32_t aNamespaceID,
|
|||
aState, nspace);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
instr = new txAttribute(name, nspace, aState.mElementContext->mMappings);
|
||||
instr = new txAttribute(Move(name), Move(nspace),
|
||||
aState.mElementContext->mMappings);
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.pushObject(instr);
|
||||
|
@ -1539,7 +1543,7 @@ txFnEndAttribute(txStylesheetCompilerState& aState)
|
|||
aState.popHandlerTable();
|
||||
nsAutoPtr<txInstruction> instr(static_cast<txInstruction*>
|
||||
(aState.popObject()));
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1566,7 +1570,7 @@ txFnStartCallTemplate(int32_t aNamespaceID,
|
|||
nsAutoPtr<txInstruction> instr(new txPushParams);
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
txExpandedName name;
|
||||
|
@ -1592,13 +1596,13 @@ txFnEndCallTemplate(txStylesheetCompilerState& aState)
|
|||
|
||||
// txCallTemplate
|
||||
nsAutoPtr<txInstruction> instr(static_cast<txInstruction*>(aState.popObject()));
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
instr = new txPopParams;
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1667,7 +1671,7 @@ txFnStartComment(int32_t aNamespaceID,
|
|||
nsAutoPtr<txInstruction> instr(new txPushStringHandler(true));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1679,7 +1683,7 @@ txFnEndComment(txStylesheetCompilerState& aState)
|
|||
nsAutoPtr<txInstruction> instr(new txComment);
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1709,7 +1713,7 @@ txFnStartCopy(int32_t aNamespaceID,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txInstruction> instr(copy.forget());
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = parseUseAttrSets(aAttributes, aAttrCount, false, aState);
|
||||
|
@ -1724,7 +1728,7 @@ txFnEndCopy(txStylesheetCompilerState& aState)
|
|||
nsAutoPtr<txInstruction> instr(new txEndElement);
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
txCopy* copy = static_cast<txCopy*>(aState.popPtr(aState.eCopy));
|
||||
|
@ -1754,10 +1758,10 @@ txFnStartCopyOf(int32_t aNamespaceID,
|
|||
aState, select);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txInstruction> instr(new txCopyOf(select));
|
||||
nsAutoPtr<txInstruction> instr(new txCopyOf(Move(select)));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return aState.pushHandlerTable(gTxIgnoreHandler);
|
||||
|
@ -1799,10 +1803,11 @@ txFnStartElement(int32_t aNamespaceID,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txInstruction> instr(
|
||||
new txStartElement(name, nspace, aState.mElementContext->mMappings));
|
||||
new txStartElement(Move(name), Move(nspace),
|
||||
aState.mElementContext->mMappings));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = parseUseAttrSets(aAttributes, aAttrCount, false, aState);
|
||||
|
@ -1817,7 +1822,7 @@ txFnEndElement(txStylesheetCompilerState& aState)
|
|||
nsAutoPtr<txInstruction> instr(new txEndElement);
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1875,7 +1880,7 @@ txFnStartForEach(int32_t aNamespaceID,
|
|||
aState, select);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txPushNewContext> pushcontext(new txPushNewContext(select));
|
||||
nsAutoPtr<txPushNewContext> pushcontext(new txPushNewContext(Move(select)));
|
||||
NS_ENSURE_TRUE(pushcontext, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.pushPtr(pushcontext, aState.ePushNewContext);
|
||||
|
@ -1885,7 +1890,7 @@ txFnStartForEach(int32_t aNamespaceID,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txInstruction> instr(pushcontext.forget());
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
instr = new txPushNullTemplateRule;
|
||||
|
@ -1894,7 +1899,7 @@ txFnStartForEach(int32_t aNamespaceID,
|
|||
rv = aState.pushPtr(instr, aState.ePushNullTemplateRule);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return aState.pushHandlerTable(gTxForEachHandler);
|
||||
|
@ -1910,7 +1915,7 @@ txFnEndForEach(txStylesheetCompilerState& aState)
|
|||
static_cast<txInstruction*>(aState.popPtr(aState.ePushNullTemplateRule));
|
||||
|
||||
nsAutoPtr<txInstruction> instr(new txLoopNodeSet(pnullrule));
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aState.popSorter();
|
||||
|
@ -1967,14 +1972,15 @@ txFnStartIf(int32_t aNamespaceID,
|
|||
aState, test);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txConditionalGoto> condGoto(new txConditionalGoto(test, nullptr));
|
||||
nsAutoPtr<txConditionalGoto> condGoto(new txConditionalGoto(Move(test),
|
||||
nullptr));
|
||||
NS_ENSURE_TRUE(condGoto, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.pushPtr(condGoto, aState.eConditionalGoto);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txInstruction> instr(condGoto.forget());
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -2006,7 +2012,7 @@ txFnStartMessage(int32_t aNamespaceID,
|
|||
nsAutoPtr<txInstruction> instr(new txPushStringHandler(false));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
txThreeState term;
|
||||
|
@ -2029,7 +2035,7 @@ static nsresult
|
|||
txFnEndMessage(txStylesheetCompilerState& aState)
|
||||
{
|
||||
nsAutoPtr<txInstruction> instr(static_cast<txInstruction*>(aState.popObject()));
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -2106,12 +2112,13 @@ txFnStartNumber(int32_t aNamespaceID,
|
|||
false, aState, groupingSize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txInstruction> instr(new txNumber(level, count, from, value,
|
||||
format,groupingSeparator,
|
||||
groupingSize));
|
||||
nsAutoPtr<txInstruction> instr(new txNumber(level, Move(count), Move(from),
|
||||
Move(value), Move(format),
|
||||
Move(groupingSeparator),
|
||||
Move(groupingSize)));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return aState.pushHandlerTable(gTxIgnoreHandler);
|
||||
|
@ -2181,7 +2188,7 @@ txFnStartParam(int32_t aNamespaceID,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txInstruction> instr(checkParam.forget());
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<Expr> select;
|
||||
|
@ -2189,7 +2196,7 @@ txFnStartParam(int32_t aNamespaceID,
|
|||
aState, select);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txSetVariable> var(new txSetVariable(name, select));
|
||||
nsAutoPtr<txSetVariable> var(new txSetVariable(name, Move(select)));
|
||||
NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (var->mValue) {
|
||||
|
@ -2230,7 +2237,7 @@ txFnEndParam(txStylesheetCompilerState& aState)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txInstruction> instr(var.forget());
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
txCheckParam* checkParam =
|
||||
|
@ -2258,7 +2265,7 @@ txFnStartPI(int32_t aNamespaceID,
|
|||
nsAutoPtr<txInstruction> instr(new txPushStringHandler(true));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<Expr> name;
|
||||
|
@ -2266,7 +2273,7 @@ txFnStartPI(int32_t aNamespaceID,
|
|||
aState, name);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
instr = new txProcessingInstruction(name);
|
||||
instr = new txProcessingInstruction(Move(name));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.pushObject(instr);
|
||||
|
@ -2282,7 +2289,7 @@ txFnEndPI(txStylesheetCompilerState& aState)
|
|||
{
|
||||
nsAutoPtr<txInstruction> instr(static_cast<txInstruction*>
|
||||
(aState.popObject()));
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -2339,7 +2346,8 @@ txFnStartSort(int32_t aNamespaceID,
|
|||
aState, caseOrder);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aState.mSorter->addSort(select, lang, dataType, order, caseOrder);
|
||||
rv = aState.mSorter->addSort(Move(select), Move(lang), Move(dataType),
|
||||
Move(order), Move(caseOrder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return aState.pushHandlerTable(gTxIgnoreHandler);
|
||||
|
@ -2394,7 +2402,7 @@ txFnTextText(const nsAString& aStr, txStylesheetCompilerState& aState)
|
|||
nsAutoPtr<txInstruction> instr(new txText(aStr, aState.mDOE));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -2426,10 +2434,10 @@ txFnStartValueOf(int32_t aNamespaceID,
|
|||
aState, select);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txInstruction> instr(new txValueOf(select, doe == eTrue));
|
||||
nsAutoPtr<txInstruction> instr(new txValueOf(Move(select), doe == eTrue));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return aState.pushHandlerTable(gTxIgnoreHandler);
|
||||
|
@ -2469,7 +2477,7 @@ txFnStartVariable(int32_t aNamespaceID,
|
|||
aState, select);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txSetVariable> var(new txSetVariable(name, select));
|
||||
nsAutoPtr<txSetVariable> var(new txSetVariable(name, Move(select)));
|
||||
NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (var->mValue) {
|
||||
|
@ -2511,7 +2519,7 @@ txFnEndVariable(txStylesheetCompilerState& aState)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txInstruction> instr(var.forget());
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -2528,7 +2536,7 @@ txFnStartElementStartRTF(int32_t aNamespaceID,
|
|||
nsAutoPtr<txInstruction> instr(new txPushRTFHandler);
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aState.mHandlerTable = gTxTemplateHandler;
|
||||
|
@ -2544,7 +2552,7 @@ txFnTextStartRTF(const nsAString& aStr, txStylesheetCompilerState& aState)
|
|||
nsAutoPtr<txInstruction> instr(new txPushRTFHandler);
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aState.mHandlerTable = gTxTemplateHandler;
|
||||
|
@ -2572,14 +2580,15 @@ txFnStartWhen(int32_t aNamespaceID,
|
|||
aState, test);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txConditionalGoto> condGoto(new txConditionalGoto(test, nullptr));
|
||||
nsAutoPtr<txConditionalGoto> condGoto(new txConditionalGoto(Move(test),
|
||||
nullptr));
|
||||
NS_ENSURE_TRUE(condGoto, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = aState.pushPtr(condGoto, aState.eConditionalGoto);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txInstruction> instr(condGoto.forget());
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return aState.pushHandlerTable(gTxTemplateHandler);
|
||||
|
@ -2596,7 +2605,7 @@ txFnEndWhen(txStylesheetCompilerState& aState)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txInstruction> instr(gotoinstr.forget());
|
||||
rv = aState.addInstruction(instr);
|
||||
rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
txConditionalGoto* condGoto =
|
||||
|
@ -2634,7 +2643,7 @@ txFnStartWithParam(int32_t aNamespaceID,
|
|||
aState, select);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoPtr<txSetParam> var(new txSetParam(name, select));
|
||||
nsAutoPtr<txSetParam> var(new txSetParam(name, Move(select)));
|
||||
NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (var->mValue) {
|
||||
|
@ -2671,7 +2680,7 @@ txFnEndWithParam(txStylesheetCompilerState& aState)
|
|||
}
|
||||
|
||||
nsAutoPtr<txInstruction> instr(var.forget());
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -2713,7 +2722,7 @@ txFnEndUnknownInstruction(txStylesheetCompilerState& aState)
|
|||
nsAutoPtr<txInstruction> instr(new txErrorInstruction());
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = aState.addInstruction(instr);
|
||||
nsresult rv = aState.addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
#include "txStylesheetCompiler.h"
|
||||
#include "txStylesheetCompileHandlers.h"
|
||||
|
@ -336,7 +337,7 @@ txStylesheetCompiler::endElement()
|
|||
nsAutoPtr<txInstruction> instr(new txRemoveVariable(var->mName));
|
||||
NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = addInstruction(instr);
|
||||
rv = addInstruction(Move(instr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mInScopeVariables.RemoveElementAt(i);
|
||||
|
@ -484,7 +485,7 @@ txStylesheetCompiler::ensureNewElementContext()
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mElementContext.forget();
|
||||
mElementContext = context;
|
||||
mElementContext = Move(context);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -723,7 +724,7 @@ txStylesheetCompilerState::closeInstructionContainer()
|
|||
}
|
||||
|
||||
nsresult
|
||||
txStylesheetCompilerState::addInstruction(nsAutoPtr<txInstruction> aInstruction)
|
||||
txStylesheetCompilerState::addInstruction(nsAutoPtr<txInstruction>&& aInstruction)
|
||||
{
|
||||
NS_PRECONDITION(mNextInstrPtr, "adding instruction outside container");
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ public:
|
|||
nsresult addToplevelItem(txToplevelItem* aItem);
|
||||
nsresult openInstructionContainer(txInstructionContainer* aContainer);
|
||||
void closeInstructionContainer();
|
||||
nsresult addInstruction(nsAutoPtr<txInstruction> aInstruction);
|
||||
nsresult addInstruction(nsAutoPtr<txInstruction>&& aInstruction);
|
||||
nsresult loadIncludedStylesheet(const nsAString& aURI);
|
||||
nsresult loadImportedStylesheet(const nsAString& aURI,
|
||||
txStylesheet::ImportFrame* aFrame);
|
||||
|
|
|
@ -4,10 +4,14 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "txToplevelItems.h"
|
||||
|
||||
#include "mozilla/Move.h"
|
||||
#include "txStylesheet.h"
|
||||
#include "txInstructions.h"
|
||||
#include "txXSLTPatterns.h"
|
||||
|
||||
using mozilla::Move;
|
||||
|
||||
TX_IMPL_GETTYPE(txAttributeSetItem, txToplevelItem::attributeSet)
|
||||
TX_IMPL_GETTYPE(txImportItem, txToplevelItem::import)
|
||||
TX_IMPL_GETTYPE(txOutputItem, txToplevelItem::output)
|
||||
|
@ -35,18 +39,20 @@ txStripSpaceItem::addStripSpaceTest(txStripSpaceTest* aStripSpaceTest)
|
|||
|
||||
TX_IMPL_GETTYPE(txTemplateItem, txToplevelItem::templ)
|
||||
|
||||
txTemplateItem::txTemplateItem(nsAutoPtr<txPattern> aMatch,
|
||||
txTemplateItem::txTemplateItem(nsAutoPtr<txPattern>&& aMatch,
|
||||
const txExpandedName& aName,
|
||||
const txExpandedName& aMode, double aPrio)
|
||||
: mMatch(aMatch), mName(aName), mMode(aMode), mPrio(aPrio)
|
||||
: mMatch(Move(aMatch)), mName(aName),
|
||||
mMode(aMode), mPrio(aPrio)
|
||||
{
|
||||
}
|
||||
|
||||
TX_IMPL_GETTYPE(txVariableItem, txToplevelItem::variable)
|
||||
|
||||
txVariableItem::txVariableItem(const txExpandedName& aName,
|
||||
nsAutoPtr<Expr> aValue,
|
||||
nsAutoPtr<Expr>&& aValue,
|
||||
bool aIsParam)
|
||||
: mName(aName), mValue(aValue), mIsParam(aIsParam)
|
||||
: mName(aName), mValue(Move(aValue)),
|
||||
mIsParam(aIsParam)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ public:
|
|||
class txTemplateItem : public txInstructionContainer
|
||||
{
|
||||
public:
|
||||
txTemplateItem(nsAutoPtr<txPattern> aMatch, const txExpandedName& aName,
|
||||
txTemplateItem(nsAutoPtr<txPattern>&& aMatch, const txExpandedName& aName,
|
||||
const txExpandedName& aMode, double aPrio);
|
||||
|
||||
TX_DECL_TOPLEVELITEM
|
||||
|
@ -122,7 +122,7 @@ public:
|
|||
class txVariableItem : public txInstructionContainer
|
||||
{
|
||||
public:
|
||||
txVariableItem(const txExpandedName& aName, nsAutoPtr<Expr> aValue,
|
||||
txVariableItem(const txExpandedName& aName, nsAutoPtr<Expr>&& aValue,
|
||||
bool aIsParam);
|
||||
|
||||
TX_DECL_TOPLEVELITEM
|
||||
|
|
|
@ -4,11 +4,15 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "txUnknownHandler.h"
|
||||
|
||||
#include "mozilla/Move.h"
|
||||
#include "txExecutionState.h"
|
||||
#include "txStringUtils.h"
|
||||
#include "txStylesheet.h"
|
||||
#include "nsGkAtoms.h"
|
||||
|
||||
using mozilla::Move;
|
||||
|
||||
txUnknownHandler::txUnknownHandler(txExecutionState* aEs)
|
||||
: mEs(aEs),
|
||||
mFlushed(false)
|
||||
|
@ -192,6 +196,6 @@ nsresult txUnknownHandler::createHandlerAndFlush(bool aHTMLRoot,
|
|||
// Let go of out buffer as soon as we're done flushing it, we're not going
|
||||
// to need it anymore from this point on (all hooks get forwarded to
|
||||
// mEs->mResultHandler.
|
||||
nsAutoPtr<txResultBuffer> buffer(mBuffer);
|
||||
nsAutoPtr<txResultBuffer> buffer(Move(mBuffer));
|
||||
return buffer->flushToHandler(mEs->mResultHandler);
|
||||
}
|
||||
|
|
|
@ -484,9 +484,6 @@ class MOZ_NONHEAP_CLASS Handle : public js::HandleBase<T>
|
|||
bool operator!=(const T &other) const { return *ptr != other; }
|
||||
bool operator==(const T &other) const { return *ptr == other; }
|
||||
|
||||
/* Change this handle to point to the same rooted location RHS does. */
|
||||
void repoint(const Handle &rhs) { ptr = rhs.address(); }
|
||||
|
||||
private:
|
||||
Handle() {}
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ C1Spewer::beginFunction(MIRGraph *graph, HandleScript script)
|
|||
return;
|
||||
|
||||
this->graph = graph;
|
||||
this->script.repoint(script);
|
||||
|
||||
fprintf(spewout_, "begin_compilation\n");
|
||||
if (script) {
|
||||
|
|
|
@ -26,12 +26,11 @@ class LInstruction;
|
|||
class C1Spewer
|
||||
{
|
||||
MIRGraph *graph;
|
||||
HandleScript script;
|
||||
FILE *spewout_;
|
||||
|
||||
public:
|
||||
C1Spewer()
|
||||
: graph(nullptr), script(NullPtr()), spewout_(nullptr)
|
||||
: graph(nullptr), spewout_(nullptr)
|
||||
{ }
|
||||
|
||||
bool init(const char *path);
|
||||
|
|
|
@ -151,7 +151,6 @@ IonSpewer::beginFunction(MIRGraph *graph, HandleScript function)
|
|||
}
|
||||
|
||||
this->graph = graph;
|
||||
this->function.repoint(function);
|
||||
|
||||
c1Spewer.beginFunction(graph, function);
|
||||
jsonSpewer.beginFunction(function);
|
||||
|
|
|
@ -97,14 +97,13 @@ class IonSpewer
|
|||
{
|
||||
private:
|
||||
MIRGraph *graph;
|
||||
JS::HandleScript function;
|
||||
C1Spewer c1Spewer;
|
||||
JSONSpewer jsonSpewer;
|
||||
bool inited_;
|
||||
|
||||
public:
|
||||
IonSpewer()
|
||||
: graph(nullptr), function(NullPtr()), inited_(false)
|
||||
: graph(nullptr), inited_(false)
|
||||
{ }
|
||||
|
||||
// File output is terminated safely upon destruction.
|
||||
|
|
|
@ -803,7 +803,24 @@ WorkerThread::handleIonWorkload()
|
|||
JS_ASSERT(WorkerThreadState().canStartIonCompile());
|
||||
JS_ASSERT(idle());
|
||||
|
||||
ionBuilder = WorkerThreadState().ionWorklist().popCopy();
|
||||
// Find the ionBuilder with the script having the highest usecount.
|
||||
GlobalWorkerThreadState::IonBuilderVector &ionWorklist = WorkerThreadState().ionWorklist();
|
||||
size_t highest = 0;
|
||||
for (size_t i = 1; i < ionWorklist.length(); i++) {
|
||||
if (ionWorklist[i]->script()->getUseCount() >
|
||||
ionWorklist[highest]->script()->getUseCount())
|
||||
{
|
||||
highest = i;
|
||||
}
|
||||
}
|
||||
ionBuilder = ionWorklist[highest];
|
||||
|
||||
// Pop the top IonBuilder and move it to the original place of the
|
||||
// IonBuilder we took to start compiling. If both are the same, only pop.
|
||||
if (highest != ionWorklist.length() - 1)
|
||||
ionWorklist[highest] = ionWorklist.popCopy();
|
||||
else
|
||||
ionWorklist.popBack();
|
||||
|
||||
TraceLogger *logger = TraceLoggerForCurrentThread();
|
||||
AutoTraceLog logScript(logger, TraceLogCreateTextId(logger, ionBuilder->script()));
|
||||
|
|
|
@ -798,9 +798,11 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
|
|||
reflowState.ComputedLogicalOffsets().ConvertTo(frameWM, stateWM);
|
||||
}
|
||||
|
||||
// Apply start margins (as appropriate) to the frame computing the
|
||||
// new starting x,y coordinates for the frame.
|
||||
ApplyStartMargin(pfd, reflowState);
|
||||
// Calculate whether the the frame should have a start margin and
|
||||
// subtract the margin from the available width if necessary.
|
||||
// The margin will be applied to the starting inline coordinates of
|
||||
// the frame in CanPlaceFrame() after reflowing the frame.
|
||||
AllowForStartMargin(pfd, reflowState);
|
||||
}
|
||||
// if isText(), no need to propagate NS_FRAME_IS_DIRTY from the parent,
|
||||
// because reflow doesn't look at the dirty bits on the frame being reflowed.
|
||||
|
@ -1055,15 +1057,14 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
|
|||
}
|
||||
|
||||
void
|
||||
nsLineLayout::ApplyStartMargin(PerFrameData* pfd,
|
||||
nsHTMLReflowState& aReflowState)
|
||||
nsLineLayout::AllowForStartMargin(PerFrameData* pfd,
|
||||
nsHTMLReflowState& aReflowState)
|
||||
{
|
||||
NS_ASSERTION(!aReflowState.IsFloating(),
|
||||
"How'd we get a floated inline frame? "
|
||||
"The frame ctor should've dealt with this.");
|
||||
|
||||
WritingMode frameWM = pfd->mFrame->GetWritingMode();
|
||||
WritingMode lineWM = mRootSpan->mWritingMode;
|
||||
|
||||
// Only apply start-margin on the first-in flow for inline frames,
|
||||
// and make sure to not apply it to any inline other than the first
|
||||
|
@ -1079,21 +1080,7 @@ nsLineLayout::ApplyStartMargin(PerFrameData* pfd,
|
|||
// Zero this out so that when we compute the max-element-width of
|
||||
// the frame we will properly avoid adding in the starting margin.
|
||||
pfd->mMargin.IStart(frameWM) = 0;
|
||||
}
|
||||
if ((pfd->mFrame->LastInFlow()->GetNextContinuation() ||
|
||||
pfd->mFrame->FrameIsNonLastInIBSplit())
|
||||
&& !pfd->GetFlag(PFD_ISLETTERFRAME)) {
|
||||
pfd->mMargin.IEnd(frameWM) = 0;
|
||||
}
|
||||
nscoord startMargin = pfd->mMargin.ConvertTo(lineWM, frameWM).IStart(lineWM);
|
||||
if (startMargin) {
|
||||
// In RTL mode, we will only apply the start margin to the frame bounds
|
||||
// after we finish flowing the frame and know more accurately whether we
|
||||
// want to skip the margins.
|
||||
if (lineWM.IsBidiLTR() && frameWM.IsBidiLTR()) {
|
||||
pfd->mBounds.IStart(lineWM) += startMargin;
|
||||
}
|
||||
|
||||
} else {
|
||||
NS_WARN_IF_FALSE(NS_UNCONSTRAINEDSIZE != aReflowState.AvailableWidth(),
|
||||
"have unconstrained width; this should only result from "
|
||||
"very large sizes, not attempts at intrinsic width "
|
||||
|
@ -1103,7 +1090,7 @@ nsLineLayout::ApplyStartMargin(PerFrameData* pfd,
|
|||
// in the reflow state), adjust available width to account for the
|
||||
// start margin. The end margin will be accounted for when we
|
||||
// finish flowing the frame.
|
||||
aReflowState.AvailableWidth() -= startMargin;
|
||||
aReflowState.AvailableWidth() -= pfd->mMargin.IStart(frameWM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1161,10 +1148,6 @@ nsLineLayout::CanPlaceFrame(PerFrameData* pfd,
|
|||
* For box-decoration-break:clone we apply the end margin on all
|
||||
* continuations (that are not letter frames).
|
||||
*/
|
||||
if (pfd->mFrame->GetPrevContinuation() ||
|
||||
pfd->mFrame->FrameIsNonFirstInIBSplit()) {
|
||||
pfd->mMargin.IStart(frameWM) = 0;
|
||||
}
|
||||
if ((NS_FRAME_IS_NOT_COMPLETE(aStatus) ||
|
||||
pfd->mFrame->LastInFlow()->GetNextContinuation() ||
|
||||
pfd->mFrame->FrameIsNonLastInIBSplit()) &&
|
||||
|
@ -1173,13 +1156,14 @@ nsLineLayout::CanPlaceFrame(PerFrameData* pfd,
|
|||
NS_STYLE_BOX_DECORATION_BREAK_SLICE) {
|
||||
pfd->mMargin.IEnd(frameWM) = 0;
|
||||
}
|
||||
|
||||
// Convert the frame's margins to the line's writing mode and apply
|
||||
// the start margin to the frame bounds.
|
||||
LogicalMargin usedMargins = pfd->mMargin.ConvertTo(lineWM, frameWM);
|
||||
nscoord startMargin = usedMargins.IStart(lineWM);
|
||||
nscoord endMargin = usedMargins.IEnd(lineWM);
|
||||
|
||||
if (!(lineWM.IsBidiLTR() && frameWM.IsBidiLTR())) {
|
||||
pfd->mBounds.IStart(lineWM) += startMargin;
|
||||
}
|
||||
pfd->mBounds.IStart(lineWM) += startMargin;
|
||||
|
||||
PerSpanData* psd = mCurrentSpan;
|
||||
if (psd->mNoWrap) {
|
||||
|
|
|
@ -528,8 +528,8 @@ protected:
|
|||
|
||||
void PushFrame(nsIFrame* aFrame);
|
||||
|
||||
void ApplyStartMargin(PerFrameData* pfd,
|
||||
nsHTMLReflowState& aReflowState);
|
||||
void AllowForStartMargin(PerFrameData* pfd,
|
||||
nsHTMLReflowState& aReflowState);
|
||||
|
||||
bool CanPlaceFrame(PerFrameData* pfd,
|
||||
bool aNotSafeToBreak,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
#include "nsCSSParser.h"
|
||||
#include "nsCSSProps.h"
|
||||
|
@ -3575,7 +3576,7 @@ CSSParserImpl::ParsePageRule(RuleAppendFunc aAppendFunc, void* aData)
|
|||
}
|
||||
|
||||
// Takes ownership of declaration.
|
||||
nsRefPtr<nsCSSPageRule> rule = new nsCSSPageRule(declaration);
|
||||
nsRefPtr<nsCSSPageRule> rule = new nsCSSPageRule(Move(declaration));
|
||||
|
||||
(*aAppendFunc)(rule, aData);
|
||||
return true;
|
||||
|
@ -3599,7 +3600,7 @@ CSSParserImpl::ParseKeyframeRule()
|
|||
|
||||
// Takes ownership of declaration, and steals contents of selectorList.
|
||||
nsRefPtr<nsCSSKeyframeRule> rule =
|
||||
new nsCSSKeyframeRule(selectorList, declaration);
|
||||
new nsCSSKeyframeRule(selectorList, Move(declaration));
|
||||
|
||||
return rule.forget();
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#define nsCSSRules_h_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/css/GroupRule.h"
|
||||
|
@ -421,8 +422,8 @@ class nsCSSKeyframeRule MOZ_FINAL : public mozilla::css::Rule,
|
|||
public:
|
||||
// WARNING: Steals the contents of aKeys *and* aDeclaration
|
||||
nsCSSKeyframeRule(InfallibleTArray<float>& aKeys,
|
||||
nsAutoPtr<mozilla::css::Declaration> aDeclaration)
|
||||
: mDeclaration(aDeclaration)
|
||||
nsAutoPtr<mozilla::css::Declaration>&& aDeclaration)
|
||||
: mDeclaration(mozilla::Move(aDeclaration))
|
||||
{
|
||||
mKeys.SwapElements(aKeys);
|
||||
}
|
||||
|
@ -548,8 +549,8 @@ class nsCSSPageRule MOZ_FINAL : public mozilla::css::Rule,
|
|||
{
|
||||
public:
|
||||
// WARNING: Steals the contents of aDeclaration
|
||||
nsCSSPageRule(nsAutoPtr<mozilla::css::Declaration> aDeclaration)
|
||||
: mDeclaration(aDeclaration),
|
||||
nsCSSPageRule(nsAutoPtr<mozilla::css::Declaration>&& aDeclaration)
|
||||
: mDeclaration(mozilla::Move(aDeclaration)),
|
||||
mImportantRule(nullptr)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -466,7 +466,7 @@ pref("breakpad.reportURL", "https://crash-stats.mozilla.com/report/index/");
|
|||
pref("app.support.baseURL", "http://support.mozilla.org/1/mobile/%VERSION%/%OS%/%LOCALE%/");
|
||||
// Used to submit data to input from about:feedback
|
||||
pref("app.feedback.postURL", "https://input.mozilla.org/%LOCALE%/feedback");
|
||||
pref("app.privacyURL", "https://www.mozilla.org/legal/privacy/firefox.html");
|
||||
pref("app.privacyURL", "https://www.mozilla.org/privacy/firefox/");
|
||||
pref("app.creditsURL", "http://www.mozilla.org/credits/");
|
||||
pref("app.channelURL", "http://www.mozilla.org/%LOCALE%/firefox/channel/");
|
||||
#if MOZ_UPDATE_CHANNEL == aurora
|
||||
|
|
|
@ -6,11 +6,14 @@ package org.mozilla.gecko;
|
|||
|
||||
import org.mozilla.gecko.widget.GeckoPopupMenu;
|
||||
|
||||
import android.view.Gravity;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
class ActionModeCompat implements GeckoPopupMenu.OnMenuItemClickListener,
|
||||
GeckoPopupMenu.OnMenuItemLongClickListener,
|
||||
View.OnClickListener {
|
||||
private final String LOGTAG = "GeckoActionModeCompat";
|
||||
|
||||
|
@ -93,9 +96,31 @@ class ActionModeCompat implements GeckoPopupMenu.OnMenuItemClickListener,
|
|||
return false;
|
||||
}
|
||||
|
||||
/* GeckoPopupMenu.onMenuItemLongClickListener */
|
||||
@Override
|
||||
public boolean onMenuItemLongClick(MenuItem item) {
|
||||
showTooltip(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* View.OnClickListener*/
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mPresenter.endActionModeCompat();
|
||||
}
|
||||
|
||||
private void showTooltip(MenuItem item) {
|
||||
// Computes the tooltip toast screen position (shown when long-tapping the menu item) with regards to the
|
||||
// menu item's position (i.e below the item and slightly to the left)
|
||||
int[] location = new int[2];
|
||||
final View view = item.getActionView();
|
||||
view.getLocationOnScreen(location);
|
||||
|
||||
int xOffset = location[0] - view.getWidth();
|
||||
int yOffset = location[1] + view.getHeight() / 2;
|
||||
|
||||
Toast toast = Toast.makeText(view.getContext(), item.getTitle(), Toast.LENGTH_SHORT);
|
||||
toast.setGravity(Gravity.TOP|Gravity.LEFT, xOffset, yOffset);
|
||||
toast.show();
|
||||
}
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче