Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2013-10-23 14:56:19 +02:00
commit d096ae1b2a
79 changed files with 2721 additions and 760 deletions

View File

@ -1,4 +1,4 @@
{
"revision": "ef355aa8244d698a5b226ac4ef2408a2eb0812bb",
"revision": "a57a913f1dd723afa191124f27b8d9fc4b0cb1c0",
"repo_path": "/integration/gaia-central"
}

View File

@ -78,15 +78,18 @@ const EVENTS = {
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
let promise = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js").Promise;
Cu.import("resource:///modules/devtools/shared/event-emitter.js");
Cu.import("resource:///modules/devtools/sourceeditor/source-editor.jsm");
Cu.import("resource:///modules/devtools/BreadcrumbsWidget.jsm");
Cu.import("resource:///modules/devtools/SideMenuWidget.jsm");
Cu.import("resource:///modules/devtools/VariablesView.jsm");
Cu.import("resource:///modules/devtools/VariablesViewController.jsm");
Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
const require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
const Editor = require("devtools/sourceeditor/editor");
const promise = require("sdk/core/promise");
const DebuggerEditor = require("devtools/sourceeditor/debugger.js");
XPCOMUtils.defineLazyModuleGetter(this, "Parser",
"resource:///modules/devtools/Parser.jsm");
@ -608,7 +611,7 @@ StackFrames.prototype = {
* Handler for the thread client's resumed notification.
*/
_onResumed: function() {
DebuggerView.editor.setDebugLocation(-1);
DebuggerView.editor.clearDebugLocation();
// Prepare the watch expression evaluation string for the next pause.
if (!this._isWatchExpressionsEvaluation) {
@ -1434,7 +1437,6 @@ EventListeners.prototype = {
* Handles all the breakpoints in the current debugger.
*/
function Breakpoints() {
this._onEditorBreakpointChange = this._onEditorBreakpointChange.bind(this);
this._onEditorBreakpointAdd = this._onEditorBreakpointAdd.bind(this);
this._onEditorBreakpointRemove = this._onEditorBreakpointRemove.bind(this);
this.addBreakpoint = this.addBreakpoint.bind(this);
@ -1457,8 +1459,8 @@ Breakpoints.prototype = {
* A promise that is resolved when the breakpoints finishes initializing.
*/
initialize: function() {
DebuggerView.editor.addEventListener(
SourceEditor.EVENTS.BREAKPOINT_CHANGE, this._onEditorBreakpointChange);
DebuggerView.editor.on("breakpointAdded", this._onEditorBreakpointAdd);
DebuggerView.editor.on("breakpointRemoved", this._onEditorBreakpointRemove);
// Initialization is synchronous, for now.
return promise.resolve(null);
@ -1471,34 +1473,21 @@ Breakpoints.prototype = {
* A promise that is resolved when the breakpoints finishes destroying.
*/
destroy: function() {
DebuggerView.editor.removeEventListener(
SourceEditor.EVENTS.BREAKPOINT_CHANGE, this._onEditorBreakpointChange);
DebuggerView.editor.off("breakpointAdded", this._onEditorBreakpointAdd);
DebuggerView.editor.off("breakpointRemoved", this._onEditorBreakpointRemove);
return this.removeAllBreakpoints();
},
/**
* Event handler for breakpoint changes that happen in the editor. This
* function syncs the breakpoints in the editor to those in the debugger.
*
* @param object aEvent
* The SourceEditor.EVENTS.BREAKPOINT_CHANGE event object.
*/
_onEditorBreakpointChange: function(aEvent) {
aEvent.added.forEach(this._onEditorBreakpointAdd, this);
aEvent.removed.forEach(this._onEditorBreakpointRemove, this);
},
/**
* Event handler for new breakpoints that come from the editor.
*
* @param object aEditorBreakpoint
* The breakpoint object coming from the editor.
* @param number aLine
* Line number where breakpoint was set.
*/
_onEditorBreakpointAdd: function(aEditorBreakpoint) {
_onEditorBreakpointAdd: function(_, aLine) {
let url = DebuggerView.Sources.selectedValue;
let line = aEditorBreakpoint.line + 1;
let location = { url: url, line: line };
let location = { url: url, line: aLine + 1 };
// Initialize the breakpoint, but don't update the editor, since this
// callback is invoked because a breakpoint was added in the editor itself.
@ -1511,26 +1500,25 @@ Breakpoints.prototype = {
DebuggerView.editor.addBreakpoint(aBreakpointClient.location.line - 1);
}
// Notify that we've shown a breakpoint in the source editor.
window.emit(EVENTS.BREAKPOINT_SHOWN, aEditorBreakpoint);
window.emit(EVENTS.BREAKPOINT_SHOWN);
});
},
/**
* Event handler for breakpoints that are removed from the editor.
*
* @param object aEditorBreakpoint
* The breakpoint object that was removed from the editor.
* @param number aLine
* Line number where breakpoint was removed.
*/
_onEditorBreakpointRemove: function(aEditorBreakpoint) {
_onEditorBreakpointRemove: function(_, aLine) {
let url = DebuggerView.Sources.selectedValue;
let line = aEditorBreakpoint.line + 1;
let location = { url: url, line: line };
let location = { url: url, line: aLine + 1 };
// Destroy the breakpoint, but don't update the editor, since this callback
// is invoked because a breakpoint was removed from the editor itself.
this.removeBreakpoint(location, { noEditorUpdate: true }).then(() => {
// Notify that we've hidden a breakpoint in the source editor.
window.emit(EVENTS.BREAKPOINT_HIDDEN, aEditorBreakpoint);
window.emit(EVENTS.BREAKPOINT_HIDDEN);
});
},
@ -1644,7 +1632,7 @@ Breakpoints.prototype = {
// after the target navigated). Note that this will get out of sync
// if the source text contents change.
let line = aBreakpointClient.location.line - 1;
aBreakpointClient.text = DebuggerView.getEditorLineText(line).trim();
aBreakpointClient.text = DebuggerView.editor.getText(line).trim();
// Show the breakpoint in the editor and breakpoints pane, and resolve.
this._showBreakpoint(aBreakpointClient, aOptions);

View File

@ -14,7 +14,7 @@ function SourcesView() {
this.togglePrettyPrint = this.togglePrettyPrint.bind(this);
this._onEditorLoad = this._onEditorLoad.bind(this);
this._onEditorUnload = this._onEditorUnload.bind(this);
this._onEditorSelection = this._onEditorSelection.bind(this);
this._onEditorCursorActivity = this._onEditorCursorActivity.bind(this);
this._onEditorContextMenu = this._onEditorContextMenu.bind(this);
this._onSourceSelect = this._onSourceSelect.bind(this);
this._onSourceClick = this._onSourceClick.bind(this);
@ -479,7 +479,12 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
*/
_hideConditionalPopup: function() {
this._cbPanel.hidden = true;
this._cbPanel.hidePopup();
// Sometimes this._cbPanel doesn't have hidePopup method which doesn't
// break anything but simply outputs an exception to the console.
if (this._cbPanel.hidePopup) {
this._cbPanel.hidePopup();
}
},
/**
@ -645,30 +650,30 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
* The load listener for the source editor.
*/
_onEditorLoad: function(aName, aEditor) {
aEditor.addEventListener(SourceEditor.EVENTS.SELECTION, this._onEditorSelection, false);
aEditor.addEventListener(SourceEditor.EVENTS.CONTEXT_MENU, this._onEditorContextMenu, false);
aEditor.on("cursorActivity", this._onEditorCursorActivity);
aEditor.on("contextMenu", this._onEditorContextMenu);
},
/**
* The unload listener for the source editor.
*/
_onEditorUnload: function(aName, aEditor) {
aEditor.removeEventListener(SourceEditor.EVENTS.SELECTION, this._onEditorSelection, false);
aEditor.removeEventListener(SourceEditor.EVENTS.CONTEXT_MENU, this._onEditorContextMenu, false);
aEditor.off("cursorActivity", this._onEditorCursorActivity);
aEditor.off("contextMenu", this._onEditorContextMenu);
},
/**
* The selection listener for the source editor.
*/
_onEditorSelection: function(e) {
let { start, end } = e.newValue;
_onEditorCursorActivity: function(e) {
let editor = DebuggerView.editor;
let start = editor.getCursor("start").line + 1;
let end = editor.getCursor().line + 1;
let url = this.selectedValue;
let url = this.selectedValue;
let lineStart = DebuggerView.editor.getLineAtOffset(start) + 1;
let lineEnd = DebuggerView.editor.getLineAtOffset(end) + 1;
let location = { url: url, line: lineStart };
let location = { url: url, line: start };
if (this.getBreakpoint(location) && lineStart == lineEnd) {
if (this.getBreakpoint(location) && start == end) {
this.highlightBreakpoint(location, { noEditorUpdate: true });
} else {
this.unhighlightBreakpoint();
@ -679,9 +684,7 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
* The context menu listener for the source editor.
*/
_onEditorContextMenu: function({ x, y }) {
let offset = DebuggerView.editor.getOffsetAtLocation(x, y);
let line = DebuggerView.editor.getLineAtOffset(offset);
this._editorContextMenuLineNumber = line;
this._editorContextMenuLineNumber = DebuggerView.editor.getPositionFromCoords(x, y).line;
},
/**
@ -869,13 +872,14 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
// If this command was executed via the context menu, add the breakpoint
// on the currently hovered line in the source editor.
if (this._editorContextMenuLineNumber >= 0) {
DebuggerView.editor.setCaretPosition(this._editorContextMenuLineNumber);
DebuggerView.editor.setCursor({ line: this._editorContextMenuLineNumber, ch: 0 });
}
// Avoid placing breakpoints incorrectly when using key shortcuts.
this._editorContextMenuLineNumber = -1;
let url = DebuggerView.Sources.selectedValue;
let line = DebuggerView.editor.getCaretPosition().line + 1;
let line = DebuggerView.editor.getCursor().line + 1;
let location = { url: url, line: line };
let breakpointItem = this.getBreakpoint(location);
@ -896,13 +900,14 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
// If this command was executed via the context menu, add the breakpoint
// on the currently hovered line in the source editor.
if (this._editorContextMenuLineNumber >= 0) {
DebuggerView.editor.setCaretPosition(this._editorContextMenuLineNumber);
DebuggerView.editor.setCursor({ line: this._editorContextMenuLineNumber, ch: 0 });
}
// Avoid placing breakpoints incorrectly when using key shortcuts.
this._editorContextMenuLineNumber = -1;
let url = DebuggerView.Sources.selectedValue;
let line = DebuggerView.editor.getCaretPosition().line + 1;
let line = DebuggerView.editor.getCursor().line + 1;
let location = { url: url, line: line };
let breakpointItem = this.getBreakpoint(location);
@ -1456,7 +1461,7 @@ WatchExpressionsView.prototype = Heritage.extend(WidgetMethods, {
_onCmdAddExpression: function(aText) {
// Only add a new expression if there's no pending input.
if (this.getAllStrings().indexOf("") == -1) {
this.addExpression(aText || DebuggerView.editor.getSelectedText());
this.addExpression(aText || DebuggerView.editor.getSelection());
}
},
@ -2100,12 +2105,9 @@ GlobalSearchView.prototype = Heritage.extend(WidgetMethods, {
let url = sourceResultsItem.instance.url;
let line = lineResultsItem.instance.line;
DebuggerView.setEditorLocation(url, line + 1, { noDebug: true });
let editor = DebuggerView.editor;
let offset = editor.getCaretOffset();
let { start, length } = lineResultsItem.lineData.range;
editor.setSelection(offset + start, offset + start + length);
DebuggerView.setEditorLocation(url, line + 1, { noDebug: true });
DebuggerView.editor.extendSelection(lineResultsItem.lineData.range);
},
/**

View File

@ -861,10 +861,9 @@ FilterView.prototype = {
*/
_performLineSearch: function(aLine) {
// Make sure we're actually searching for a valid line.
if (!aLine) {
return;
if (aLine) {
DebuggerView.editor.setCursor({ line: aLine - 1, ch: 0 });
}
DebuggerView.editor.setCaretPosition(aLine - 1);
},
/**
@ -879,10 +878,8 @@ FilterView.prototype = {
if (!aToken) {
return;
}
let offset = DebuggerView.editor.find(aToken, { ignoreCase: true });
if (offset > -1) {
DebuggerView.editor.setSelection(offset, offset + aToken.length)
}
DebuggerView.editor.find(aToken);
},
/**
@ -1043,14 +1040,8 @@ FilterView.prototype = {
// Jump to the next/previous instance of the currently searched token.
if (isTokenSearch) {
let [, token] = args;
let methods = { selectNext: "findNext", selectPrev: "findPrevious" };
// Search for the token and select it.
let offset = DebuggerView.editor[methods[actionToPerform]](true);
if (offset > -1) {
DebuggerView.editor.setSelection(offset, offset + token.length)
}
let methods = { selectNext: "findNext", selectPrev: "findPrev" };
DebuggerView.editor[methods[actionToPerform]]();
return;
}
@ -1061,7 +1052,7 @@ FilterView.prototype = {
// Modify the line number and jump to it.
line += !isReturnKey ? amounts[actionToPerform] : 0;
let lineCount = DebuggerView.editor.getLineCount();
let lineCount = DebuggerView.editor.lineCount();
let lineTarget = line < 1 ? 1 : line > lineCount ? lineCount : line;
this._doSearch(SEARCH_LINE_FLAG, lineTarget);
return;
@ -1084,7 +1075,7 @@ FilterView.prototype = {
_doSearch: function(aOperator = "", aText = "") {
this._searchbox.focus();
this._searchbox.value = ""; // Need to clear value beforehand. Bug 779738.
this._searchbox.value = aOperator + (aText || DebuggerView.editor.getSelectedText());
this._searchbox.value = aOperator + (aText || DebuggerView.editor.getSelection());
},
/**

View File

@ -28,13 +28,6 @@ const SEARCH_FUNCTION_FLAG = "@";
const SEARCH_TOKEN_FLAG = "#";
const SEARCH_LINE_FLAG = ":";
const SEARCH_VARIABLE_FLAG = "*";
const DEFAULT_EDITOR_CONFIG = {
mode: SourceEditor.MODES.TEXT,
readOnly: true,
showLineNumbers: true,
showAnnotationRuler: true,
showOverviewRuler: true
};
/**
* Object defining the debugger view components.
@ -187,7 +180,7 @@ let DebuggerView = {
},
/**
* Initializes the SourceEditor instance.
* Initializes the Editor instance.
*
* @param function aCallback
* Called after the editor finishes initializing.
@ -195,11 +188,35 @@ let DebuggerView = {
_initializeEditor: function(aCallback) {
dumpn("Initializing the DebuggerView editor");
this.editor = new SourceEditor();
this.editor.init(document.getElementById("editor"), DEFAULT_EDITOR_CONFIG, () => {
// This needs to be more localizable: see bug 929234.
let extraKeys = {};
extraKeys[(Services.appinfo.OS == "Darwin" ? "Cmd-" : "Ctrl-") + "F"] = (cm) => {
DebuggerView.Filtering._doTokenSearch();
};
this.editor = new Editor({
mode: Editor.modes.text,
readOnly: true,
lineNumbers: true,
showAnnotationRuler: true,
gutters: [ "breakpoints" ],
extraKeys: extraKeys,
contextMenu: "sourceEditorContextMenu"
});
this.editor.appendTo(document.getElementById("editor")).then(() => {
this.editor.extend(DebuggerEditor);
this._loadingText = L10N.getStr("loadingText");
this._onEditorLoad(aCallback);
});
this.editor.on("gutterClick", (ev, line) => {
if (this.editor.hasBreakpoint(line)) {
this.editor.removeBreakpoint(line);
} else {
this.editor.addBreakpoint(line);
}
});
},
/**
@ -219,7 +236,7 @@ let DebuggerView = {
},
/**
* Destroys the SourceEditor instance and also executes any necessary
* Destroys the Editor instance and also executes any necessary
* post-unload operations.
*
* @param function aCallback
@ -276,9 +293,9 @@ let DebuggerView = {
* The source text content.
*/
_setEditorText: function(aTextContent = "") {
this.editor.setMode(SourceEditor.MODES.TEXT);
this.editor.setMode(Editor.modes.text);
this.editor.setText(aTextContent);
this.editor.resetUndo();
this.editor.clearHistory();
},
/**
@ -294,22 +311,24 @@ let DebuggerView = {
*/
_setEditorMode: function(aUrl, aContentType = "", aTextContent = "") {
// Avoid setting the editor mode for very large files.
// Is this still necessary? See bug 929225.
if (aTextContent.length >= SOURCE_SYNTAX_HIGHLIGHT_MAX_FILE_SIZE) {
this.editor.setMode(SourceEditor.MODES.TEXT);
return void this.editor.setMode(Editor.modes.text);
}
// Use JS mode for files with .js and .jsm extensions.
else if (SourceUtils.isJavaScript(aUrl, aContentType)) {
this.editor.setMode(SourceEditor.MODES.JAVASCRIPT);
if (SourceUtils.isJavaScript(aUrl, aContentType)) {
return void this.editor.setMode(Editor.modes.js);
}
// Use HTML mode for files in which the first non whitespace character is
// &lt;, regardless of extension.
else if (aTextContent.match(/^\s*</)) {
this.editor.setMode(SourceEditor.MODES.HTML);
}
// Unknown languange, use plain text.
else {
this.editor.setMode(SourceEditor.MODES.TEXT);
if (aTextContent.match(/^\s*</)) {
return void this.editor.setMode(Editor.modes.html);
}
// Unknown language, use text.
this.editor.setMode(Editor.modes.text);
},
/**
@ -415,6 +434,11 @@ let DebuggerView = {
let sourceItem = this.Sources.getItemByValue(aUrl);
let sourceForm = sourceItem.attachment.source;
// Once we change the editor location, it replaces editor's contents.
// This means that the debug location information is now obsolete, so
// we need to clear it. We set a new location below, in this function.
this.editor.clearDebugLocation();
// Make sure the requested source client is shown in the editor, then
// update the source editor's caret position and debug location.
return this._setEditorSource(sourceForm, aFlags).then(() => {
@ -423,35 +447,23 @@ let DebuggerView = {
if (aLine < 1) {
return;
}
if (aFlags.charOffset) {
aLine += this.editor.getLineAtOffset(aFlags.charOffset);
aLine += this.editor.getPosition(aFlags.charOffset).line;
}
if (aFlags.lineOffset) {
aLine += aFlags.lineOffset;
}
if (!aFlags.noCaret) {
this.editor.setCaretPosition(aLine - 1, aFlags.columnOffset);
}
if (!aFlags.noDebug) {
this.editor.setDebugLocation(aLine - 1, aFlags.columnOffset);
}
});
},
/**
* Gets the text in the source editor's specified line.
*
* @param number aLine [optional]
* The line to get the text from. If unspecified, it defaults to
* the current caret position.
* @return string
* The specified line's text.
*/
getEditorLineText: function(aLine) {
let line = aLine || this.editor.getCaretPosition().line;
let start = this.editor.getLineStart(line);
let end = this.editor.getLineEnd(line);
return this.editor.getText(start, end);
if (!aFlags.noCaret) {
this.editor.setCursor({ line: aLine -1, ch: aFlags.columnOffset || 0 });
}
if (!aFlags.noDebug) {
this.editor.setDebugLocation(aLine - 1);
}
}).then(null, console.error);
},
/**
@ -599,9 +611,9 @@ let DebuggerView = {
this.EventListeners.empty();
if (this.editor) {
this.editor.setMode(SourceEditor.MODES.TEXT);
this.editor.setMode(Editor.modes.text);
this.editor.setText("");
this.editor.resetUndo();
this.editor.clearHistory();
this._editorSource = {};
}
},

View File

@ -13,7 +13,6 @@
%debuggerDTD;
]>
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
<?xul-overlay href="chrome://browser/content/devtools/source-editor-overlay.xul"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
macanimationtype="document"
@ -29,7 +28,6 @@
<script type="text/javascript" src="debugger-panes.js"/>
<commandset id="editMenuCommands"/>
<commandset id="sourceEditorCommands"/>
<commandset id="debuggerCommands">
<command id="prettyPrintCommand"
@ -86,7 +84,7 @@
<popupset id="debuggerPopupset">
<menupopup id="sourceEditorContextMenu"
onpopupshowing="goUpdateSourceEditorMenuItems()">
onpopupshowing="goUpdateGlobalEditMenuItems()">
<menuitem id="se-dbg-cMenu-addBreakpoint"
label="&debuggerUI.seMenuBreak;"
key="addBreakpointKey"
@ -100,9 +98,9 @@
key="addWatchExpressionKey"
command="addWatchExpressionCommand"/>
<menuseparator/>
<menuitem id="se-cMenu-copy"/>
<menuitem id="cMenu_copy"/>
<menuseparator/>
<menuitem id="se-cMenu-selectAll"/>
<menuitem id="cMenu_selectAll"/>
<menuseparator/>
<menuitem id="se-dbg-cMenu-findFile"
label="&debuggerUI.searchFile;"

View File

@ -35,7 +35,7 @@ function test() {
is(gEditor.getBreakpoints().length, 0,
"No breakpoints currently shown in the editor.");
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAdd);
gEditor.on("breakpointAdded", onEditorBreakpointAdd);
gPanel.addBreakpoint({ url: gSources.selectedValue, line: 4 }).then(onBreakpointAdd);
}
@ -59,8 +59,8 @@ function test() {
maybeFinish();
}
function onEditorBreakpointAdd(aEvent) {
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAdd);
function onEditorBreakpointAdd() {
gEditor.off("breakpointAdded", onEditorBreakpointAdd);
is(gEditor.getBreakpoints().length, 1,
"There is only one breakpoint in the editor");

View File

@ -12,14 +12,13 @@ function test() {
requestLongerTimeout(2);
let gTab, gDebuggee, gPanel, gDebugger;
let gEditor, gSources, gBreakpoints;
let gSources, gBreakpoints;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;

View File

@ -40,7 +40,7 @@ function test() {
function verifyView({ disabled, visible }) {
return Task.spawn(function() {
// It takes a tick for the checkbox in the SideMenuWidget and the
// gutter in the SourceEditor to get updated.
// gutter in the editor to get updated.
yield waitForTick();
let breakpointItem = gSources.getBreakpoint(gBreakpointLocation);

View File

@ -54,7 +54,7 @@ function test() {
info("Add the first breakpoint.");
let location = { url: gSources.selectedValue, line: 6 };
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddFirst);
gEditor.once("breakpointAdded", onEditorBreakpointAddFirst);
gPanel.addBreakpoint(location).then(onBreakpointAddFirst);
}
@ -62,17 +62,12 @@ function test() {
let breakpointsRemoved = 0;
let editorBreakpointChanges = 0;
function onEditorBreakpointAddFirst(aEvent) {
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddFirst);
function onEditorBreakpointAddFirst(aEvent, aLine) {
editorBreakpointChanges++;
ok(aEvent,
"breakpoint1 added to the editor.");
is(aEvent.added.length, 1,
"One breakpoint added to the editor.");
is(aEvent.removed.length, 0,
"No breakpoint was removed from the editor.");
is(aEvent.added[0].line, 5,
is(aLine, 5,
"Editor breakpoint line is correct.");
is(gEditor.getBreakpoints().length, 1,
@ -108,21 +103,16 @@ function test() {
"The second source should be currently selected.");
info("Remove the first breakpoint.");
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveFirst);
gEditor.once("breakpointRemoved", onEditorBreakpointRemoveFirst);
gPanel.removeBreakpoint(aBreakpointClient.location).then(onBreakpointRemoveFirst);
}
function onEditorBreakpointRemoveFirst(aEvent) {
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveFirst);
function onEditorBreakpointRemoveFirst(aEvent, aLine) {
editorBreakpointChanges++;
ok(aEvent,
"breakpoint1 removed from the editor.");
is(aEvent.added.length, 0,
"No breakpoint was added to the editor.");
is(aEvent.removed.length, 1,
"One breakpoint was removed from the editor.");
is(aEvent.removed[0].line, 5,
is(aLine, 5,
"Editor breakpoint line is correct.");
is(gEditor.getBreakpoints().length, 0,
@ -161,16 +151,14 @@ function test() {
info("Add a breakpoint to the first source, which is not selected.");
let location = { url: gSources.values[0], line: 5 };
let options = { noEditorUpdate: true };
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddBackgroundTrap);
gEditor.on("breakpointAdded", onEditorBreakpointAddBackgroundTrap);
gPanel.addBreakpoint(location, options).then(onBreakpointAddBackground);
}
function onEditorBreakpointAddBackgroundTrap(aEvent) {
function onEditorBreakpointAddBackgroundTrap() {
// Trap listener: no breakpoint must be added to the editor when a
// breakpoint is added to a source that is not currently selected.
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddBackgroundTrap);
editorBreakpointChanges++;
ok(false, "breakpoint2 must not be added to the editor.");
}
@ -203,25 +191,20 @@ function test() {
"The second source should be currently selected.");
// Remove the trap listener.
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddBackgroundTrap);
gEditor.off("breakpointAdded", onEditorBreakpointAddBackgroundTrap);
info("Switch to the first source, which is not yet selected");
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddSwitch);
gEditor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onEditorTextChanged);
gEditor.once("breakpointAdded", onEditorBreakpointAddSwitch);
gEditor.once("change", onEditorTextChanged);
gSources.selectedIndex = 0;
}
function onEditorBreakpointAddSwitch(aEvent) {
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddSwitch);
function onEditorBreakpointAddSwitch(aEvent, aLine) {
editorBreakpointChanges++;
ok(aEvent,
"breakpoint2 added to the editor.");
is(aEvent.added.length, 1,
"One breakpoint added to the editor.");
is(aEvent.removed.length, 0,
"No breakpoint was removed from the editor.");
is(aEvent.added[0].line, 4,
is(aLine, 4,
"Editor breakpoint line is correct.");
is(gEditor.getBreakpoints().length, 1,
@ -230,13 +213,8 @@ function test() {
function onEditorTextChanged() {
// Wait for the actual text to be shown.
if (gEditor.getText() != gDebugger.L10N.getStr("loadingText")) {
onEditorTextReallyChanged();
}
}
function onEditorTextReallyChanged() {
gEditor.removeEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onEditorTextChanged);
if (gEditor.getText() == gDebugger.L10N.getStr("loadingText"))
return void gEditor.once("change", onEditorTextChanged);
is(gEditor.getText().indexOf("debugger"), -1,
"The second source is no longer displayed.");
@ -246,15 +224,15 @@ function test() {
is(gSources.values[0], gSources.selectedValue,
"The first source should be currently selected.");
let window = gEditor.editorElement.contentWindow;
let window = gEditor.container.contentWindow;
executeSoon(() => window.mozRequestAnimationFrame(onReadyForClick));
}
function onReadyForClick() {
info("Remove the second breakpoint using the mouse.");
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveSecond);
gEditor.once("breakpointRemoved", onEditorBreakpointRemoveSecond);
let iframe = gEditor.editorElement;
let iframe = gEditor.container;
let testWin = iframe.ownerDocument.defaultView;
// Flush the layout for the iframe.
@ -264,27 +242,20 @@ function test() {
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let lineOffset = gEditor.getLineStart(4);
let coords = gEditor.getLocationAtOffset(lineOffset);
let coords = gEditor.cursorCoords({ line: 4, ch: 0 });
let rect = iframe.getBoundingClientRect();
let left = rect.left + 10;
let top = rect.top + coords.y + 4;
let top = rect.top + coords.top + 4;
utils.sendMouseEventToWindow("mousedown", left, top, 0, 1, 0, false, 0, 0);
utils.sendMouseEventToWindow("mouseup", left, top, 0, 1, 0, false, 0, 0);
}
function onEditorBreakpointRemoveSecond(aEvent) {
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveSecond);
function onEditorBreakpointRemoveSecond(aEvent, aLine) {
editorBreakpointChanges++;
ok(aEvent,
"breakpoint2 removed from the editor.");
is(aEvent.added.length, 0,
"No breakpoint was added to the editor.");
is(aEvent.removed.length, 1,
"One breakpoint was removed from the editor.");
is(aEvent.removed[0].line, 4,
is(aLine, 4,
"Editor breakpoint line is correct.");
is(gEditor.getBreakpoints().length, 0,

View File

@ -181,7 +181,7 @@ function test() {
}
function setCaretPosition(aLine) {
gEditor.setCaretPosition(aLine - 1);
gEditor.setCursor({ line: aLine - 1, ch: 0 });
}
function setContextPosition(aLine) {

View File

@ -20,7 +20,7 @@ function test() {
gSources = gDebugger.DebuggerView.Sources;
gContextMenu = gDebugger.document.getElementById("sourceEditorContextMenu");
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6).then(performTest);
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6).then(performTest).then(null, info);
gDebuggee.firstCall();
});
@ -39,14 +39,14 @@ function test() {
ok(gContextMenu,
"The source editor's context menupopup is available.");
ok(gEditor.readOnly,
ok(gEditor.isReadOnly(),
"The source editor is read only.");
gEditor.focus();
gEditor.setSelection(0, 10);
gEditor.setSelection({ line: 1, ch: 0 }, { line: 1, ch: 10 });
once(gContextMenu, "popupshown").then(testContextMenu);
gContextMenu.openPopup(gEditor.editorElement, "overlap", 0, 0, true, false);
once(gContextMenu, "popupshown").then(testContextMenu).then(null, info);
gContextMenu.openPopup(gEditor.container, "overlap", 0, 0, true, false);
}
function testContextMenu() {
@ -56,21 +56,6 @@ function test() {
"#editMenuCommands found.");
ok(!document.getElementById("editMenuKeys"),
"#editMenuKeys not found.");
ok(document.getElementById("sourceEditorCommands"),
"#sourceEditorCommands found.");
// Map command ids to their expected disabled state.
let commands = {"se-cmd-undo": true, "se-cmd-redo": true,
"se-cmd-cut": true, "se-cmd-paste": true,
"se-cmd-delete": true, "cmd_findAgain": true,
"cmd_findPrevious": true, "cmd_find": false,
"cmd_gotoLine": false, "cmd_copy": false,
"se-cmd-selectAll": false};
for (let id in commands) {
is(document.getElementById(id).hasAttribute("disabled"), commands[id],
"The element with id: " + id + " hasAttribute('disabled').");
}
gContextMenu.hidePopup();
resumeDebuggerThenCloseAndFinish(gPanel);

View File

@ -37,7 +37,7 @@ function testInitialSource() {
is(gSources.itemCount, 3,
"Found the expected number of sources.");
is(gEditor.getMode(), SourceEditor.MODES.TEXT,
is(gEditor.getMode().name, "text",
"Found the expected editor mode.");
is(gEditor.getText().search(/firstCall/), -1,
"The first source is not displayed.");
@ -55,7 +55,7 @@ function testSwitch1() {
is(gSources.itemCount, 3,
"Found the expected number of sources.");
is(gEditor.getMode(), SourceEditor.MODES.JAVASCRIPT,
is(gEditor.getMode().name, "javascript",
"Found the expected editor mode.");
is(gEditor.getText().search(/firstCall/), 118,
"The first source is displayed.");
@ -73,7 +73,7 @@ function testSwitch2() {
is(gSources.itemCount, 3,
"Found the expected number of sources.");
is(gEditor.getMode(), SourceEditor.MODES.HTML,
is(gEditor.getMode().name, "htmlmixed",
"Found the expected editor mode.");
is(gEditor.getText().search(/firstCall/), -1,
"The first source is not displayed.");

View File

@ -39,7 +39,7 @@ function selectContextMenuItem() {
const menuItem = gDebugger.document.getElementById("se-dbg-cMenu-prettyPrint");
menuItem.click();
});
gContextMenu.openPopup(gEditor.editorElement, "overlap", 0, 0, true, false);
gContextMenu.openPopup(gEditor.container, "overlap", 0, 0, true, false);
}
function testSourceIsPretty() {

View File

@ -24,7 +24,7 @@ function test() {
yield waitForSourceShown(gPanel, TAB_URL);
// From this point onward, the source editor's text should never change.
once(gEditor, SourceEditor.EVENTS.TEXT_CHANGED).then(() => {
gEditor.once("change", () => {
ok(false, "The source editor text shouldn't have changed.");
});

View File

@ -40,7 +40,7 @@ function test() {
yield waitForSourceShown(gPanel, JS_URL);
// From this point onward, the source editor's text should never change.
once(gEditor, SourceEditor.EVENTS.TEXT_CHANGED).then(() => {
gEditor.once("change", () => {
ok(false, "The source editor text shouldn't have changed.");
});

View File

@ -104,7 +104,7 @@ function testSwitchPaused1() {
executeSoon(() => {
ok(isCaretPos(gPanel, 1),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), -1,
is(gEditor.getDebugLocation(), null,
"Editor debugger location is correct.");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);

View File

@ -99,7 +99,8 @@ function testSwitchPaused1() {
executeSoon(() => {
ok(isCaretPos(gPanel, 1),
"Editor caret location is correct.");
is(gEditor.getDebugLocation(), -1,
is(gEditor.getDebugLocation(), null,
"Editor debugger location is correct.");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(deferred.resolve);

View File

@ -130,7 +130,6 @@ function performTest() {
ok(isCaretPos(gPanel, 26, 11 + token.length),
"The editor didn't jump to the correct token (6).");
setText(gSearchBox, ":bogus#" + token + ";");
is(gFiltering.searchData.toSource(), '["#", [":bogus", "debugger;"]]',
"The searchbox data wasn't parsed correctly.");
@ -283,7 +282,7 @@ function performTest() {
gEditor.focus();
gEditor.setSelection(1, 5);
gEditor.setSelection.apply(gEditor, gEditor.getPosition(1, 5));
ok(isCaretPos(gPanel, 1, 6),
"The editor caret position didn't update after selecting some text.");
@ -294,7 +293,7 @@ function performTest() {
"The search field has the right initial value (1).");
gEditor.focus();
gEditor.setSelection(415, 418);
gEditor.setSelection.apply(gEditor, gEditor.getPosition(415, 418));
ok(isCaretPos(gPanel, 21, 30),
"The editor caret position didn't update after selecting some number.");

View File

@ -33,11 +33,11 @@ function test() {
function testLineSearch() {
setText(gSearchBox, ":42");
ok(isCaretPos(gPanel, 1),
ok(isCaretPos(gPanel, 7),
"The editor caret position appears to be correct (1.1).");
ok(isEditorSel(gPanel, [1, 1]),
ok(isEditorSel(gPanel, [160, 160]),
"The editor selection appears to be correct (1.1).");
is(gEditor.getSelectedText(), "",
is(gEditor.getSelection(), "",
"The editor selected text appears to be correct (1.1).");
backspaceText(gSearchBox, 1);
@ -45,7 +45,7 @@ function testLineSearch() {
"The editor caret position appears to be correct (1.2).");
ok(isEditorSel(gPanel, [110, 110]),
"The editor selection appears to be correct (1.2).");
is(gEditor.getSelectedText(), "",
is(gEditor.getSelection(), "",
"The editor selected text appears to be correct (1.2).");
backspaceText(gSearchBox, 1);
@ -53,7 +53,7 @@ function testLineSearch() {
"The editor caret position appears to be correct (1.3).");
ok(isEditorSel(gPanel, [110, 110]),
"The editor selection appears to be correct (1.3).");
is(gEditor.getSelectedText(), "",
is(gEditor.getSelection(), "",
"The editor selected text appears to be correct (1.3).");
setText(gSearchBox, ":4");
@ -61,7 +61,7 @@ function testLineSearch() {
"The editor caret position appears to be correct (1.4).");
ok(isEditorSel(gPanel, [110, 110]),
"The editor selection appears to be correct (1.4).");
is(gEditor.getSelectedText(), "",
is(gEditor.getSelection(), "",
"The editor selected text appears to be correct (1.4).");
gSearchBox.select();
@ -70,7 +70,7 @@ function testLineSearch() {
"The editor caret position appears to be correct (1.5).");
ok(isEditorSel(gPanel, [110, 110]),
"The editor selection appears to be correct (1.5).");
is(gEditor.getSelectedText(), "",
is(gEditor.getSelection(), "",
"The editor selected text appears to be correct (1.5).");
is(gSearchBox.value, "",
"The searchbox should have been cleared.");
@ -82,7 +82,7 @@ function testTokenSearch() {
"The editor caret position appears to be correct (2.1).");
ok(isEditorSel(gPanel, [153, 155]),
"The editor selection appears to be correct (2.1).");
is(gEditor.getSelectedText(), ";\"",
is(gEditor.getSelection(), ";\"",
"The editor selected text appears to be correct (2.1).");
backspaceText(gSearchBox, 1);
@ -90,7 +90,7 @@ function testTokenSearch() {
"The editor caret position appears to be correct (2.2).");
ok(isEditorSel(gPanel, [153, 154]),
"The editor selection appears to be correct (2.2).");
is(gEditor.getSelectedText(), ";",
is(gEditor.getSelection(), ";",
"The editor selected text appears to be correct (2.2).");
backspaceText(gSearchBox, 1);
@ -98,7 +98,7 @@ function testTokenSearch() {
"The editor caret position appears to be correct (2.3).");
ok(isEditorSel(gPanel, [154, 154]),
"The editor selection appears to be correct (2.3).");
is(gEditor.getSelectedText(), "",
is(gEditor.getSelection(), "",
"The editor selected text appears to be correct (2.3).");
setText(gSearchBox, "#;");
@ -106,7 +106,7 @@ function testTokenSearch() {
"The editor caret position appears to be correct (2.4).");
ok(isEditorSel(gPanel, [153, 154]),
"The editor selection appears to be correct (2.4).");
is(gEditor.getSelectedText(), ";",
is(gEditor.getSelection(), ";",
"The editor selected text appears to be correct (2.4).");
gSearchBox.select();
@ -115,7 +115,7 @@ function testTokenSearch() {
"The editor caret position appears to be correct (2.5).");
ok(isEditorSel(gPanel, [154, 154]),
"The editor selection appears to be correct (2.5).");
is(gEditor.getSelectedText(), "",
is(gEditor.getSelection(), "",
"The editor selected text appears to be correct (2.5).");
is(gSearchBox.value, "",
"The searchbox should have been cleared.");

View File

@ -87,7 +87,7 @@ function doFirstJump() {
executeSoon(() => {
ok(isCaretPos(gPanel, 5, 7),
"The editor didn't jump to the correct line (1).");
is(gEditor.getSelectedText(), "eval",
is(gEditor.getSelection(), "eval",
"The editor didn't select the correct text (1).");
deferred.resolve();
@ -115,7 +115,7 @@ function doSecondJump() {
executeSoon(() => {
ok(isCaretPos(gPanel, 6, 7),
"The editor didn't jump to the correct line (2).");
is(gEditor.getSelectedText(), "eval",
is(gEditor.getSelection(), "eval",
"The editor didn't select the correct text (2).");
deferred.resolve();
@ -143,7 +143,7 @@ function doWrapAroundJump() {
executeSoon(() => {
ok(isCaretPos(gPanel, 5, 7),
"The editor didn't jump to the correct line (3).");
is(gEditor.getSelectedText(), "eval",
is(gEditor.getSelection(), "eval",
"The editor didn't select the correct text (3).");
deferred.resolve();
@ -171,7 +171,7 @@ function doBackwardsWrapAroundJump() {
executeSoon(() => {
ok(isCaretPos(gPanel, 6, 7),
"The editor didn't jump to the correct line (4).");
is(gEditor.getSelectedText(), "eval",
is(gEditor.getSelection(), "eval",
"The editor didn't select the correct text (4).");
deferred.resolve();
@ -195,7 +195,7 @@ function testSearchTokenEmpty() {
"Not all the sources are shown after the global search (4).");
ok(isCaretPos(gPanel, 6, 7),
"The editor didn't remain at the correct line (4).");
is(gEditor.getSelectedText(), "",
is(gEditor.getSelection(), "",
"The editor shouldn't keep the previous text selected (4).");
is(gSearchView.itemCount, 0,

View File

@ -100,7 +100,7 @@ function testClickLineToJump() {
ok(isCaretPos(gPanel, 1, 5),
"The editor didn't jump to the correct line (1).");
is(gEditor.getSelectedText(), "A",
is(gEditor.getSelection(), "A",
"The editor didn't select the correct text (1).");
ok(gSources.selectedValue.contains("-01.js"),
"The currently shown source is incorrect (1).");
@ -129,7 +129,7 @@ function testClickMatchToJump() {
ok(isCaretPos(gPanel, 6, 6),
"The editor didn't jump to the correct line (2).");
is(gEditor.getSelectedText(), "a",
is(gEditor.getSelection(), "a",
"The editor didn't select the correct text (2).");
ok(gSources.selectedValue.contains("-02.js"),
"The currently shown source is incorrect (2).");

View File

@ -8,7 +8,7 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gEditor, gSources, gSearchView, gSearchBox;
let gSources, gSearchView, gSearchBox;
function test() {
// Debug test slaves are a bit slow at this test.
@ -19,7 +19,6 @@ function test() {
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gSearchView = gDebugger.DebuggerView.FilteredSources;
gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
@ -230,7 +229,6 @@ registerCleanupFunction(function() {
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
gSearchView = null;
gSearchBox = null;

View File

@ -8,7 +8,7 @@
const TAB_URL = EXAMPLE_URL + "doc_editor-mode.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gEditor, gSources, gSourceUtils, gSearchView, gSearchBox;
let gSources, gSourceUtils, gSearchView, gSearchBox;
function test() {
// Debug test slaves are a bit slow at this test.
@ -19,7 +19,6 @@ function test() {
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
gSourceUtils = gDebugger.SourceUtils;
gSearchView = gDebugger.DebuggerView.FilteredSources;
@ -272,7 +271,6 @@ registerCleanupFunction(function() {
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
gSourceUtils = null;
gSearchView = null;

View File

@ -9,7 +9,7 @@
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gEditor, gSearchBox, gSearchBoxPanel;
let gSearchBox, gSearchBoxPanel;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
@ -17,7 +17,6 @@ function test() {
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
gSearchBoxPanel = gDebugger.DebuggerView.Filtering._searchboxHelpPanel;
@ -56,7 +55,6 @@ registerCleanupFunction(function() {
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSearchBox = null;
gSearchBoxPanel = null;
});

View File

@ -44,7 +44,7 @@ function tryShowPopup() {
"The editor caret position appears to be correct.");
ok(isEditorSel(gPanel, [125, 131]),
"The editor selection appears to be correct.");
is(gEditor.getSelectedText(), "Call()",
is(gEditor.getSelection(), "Call()",
"The editor selected text appears to be correct.");
is(gSearchBoxPanel.state, "closed",
@ -68,7 +68,7 @@ function testFocusLost() {
"The editor caret position appears to be correct after gaining focus.");
ok(isEditorSel(gPanel, [165, 165]),
"The editor selection appears to be correct after gaining focus.");
is(gEditor.getSelectedText(), "",
is(gEditor.getSelection(), "",
"The editor selected text appears to be correct after gaining focus.");
is(gSearchBoxPanel.state, "closed",

View File

@ -85,7 +85,7 @@ function test() {
let url = href + leaf;
let label = gUtils.getSourceLabel(url);
let trimmedLabel = gUtils.trimUrlLength(label);
gSources.push([trimmedLabel, url]);
gSources.push([trimmedLabel, url], { attachment: {}});
}
info("Source labels:");

View File

@ -132,7 +132,7 @@ function testAfterResume() {
"Should have no frames after resume.");
ok(isCaretPos(gPanel, 5),
"Editor caret location is correct after resume.");
is(gEditor.getDebugLocation(), -1,
is(gEditor.getDebugLocation(), null,
"Editor debug location is correct after resume.");
deferred.resolve();

View File

@ -9,7 +9,7 @@
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gEditor, gVariables, gSearchBox;
let gVariables, gSearchBox;
function test() {
// Debug test slaves are a bit slow at this test.
@ -20,7 +20,6 @@ function test() {
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gVariables = gDebugger.DebuggerView.Variables;
gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
@ -233,7 +232,6 @@ registerCleanupFunction(function() {
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gVariables = null;
gSearchBox = null;
});

View File

@ -12,14 +12,13 @@ function test() {
requestLongerTimeout(2);
let gTab, gDebuggee, gPanel, gDebugger;
let gEditor, gWatch, gVariables;
let gWatch, gVariables;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gWatch = gDebugger.DebuggerView.WatchExpressions;
gVariables = gDebugger.DebuggerView.Variables;

View File

@ -20,7 +20,6 @@ let { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils
let { BrowserDebuggerProcess } = Cu.import("resource:///modules/devtools/DebuggerProcess.jsm", {});
let { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
let { DebuggerClient } = Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {});
let { SourceEditor } = Cu.import("resource:///modules/devtools/sourceeditor/source-editor.jsm", {});
let { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
let TargetFactory = devtools.TargetFactory;
let Toolbox = devtools.Toolbox;
@ -246,9 +245,9 @@ function ensureSourceIs(aPanel, aUrl, aWaitFlag = false) {
}
function waitForCaretUpdated(aPanel, aLine, aCol = 1) {
return waitForEditorEvents(aPanel, SourceEditor.EVENTS.SELECTION).then(() => {
let caret = aPanel.panelWin.DebuggerView.editor.getCaretPosition();
info("Caret updated: " + (caret.line + 1) + ", " + (caret.col + 1));
return waitForEditorEvents(aPanel, "cursorActivity").then(() => {
let cursor = aPanel.panelWin.DebuggerView.editor.getCursor();
info("Caret updated: " + (cursor.line + 1) + ", " + (cursor.ch + 1));
if (!isCaretPos(aPanel, aLine, aCol)) {
return waitForCaretUpdated(aPanel, aLine, aCol);
@ -272,16 +271,19 @@ function ensureCaretAt(aPanel, aLine, aCol = 1, aWaitFlag = false) {
function isCaretPos(aPanel, aLine, aCol = 1) {
let editor = aPanel.panelWin.DebuggerView.editor;
let caret = editor.getCaretPosition();
let cursor = editor.getCursor();
// Source editor starts counting line and column numbers from 0.
info("Current editor caret position: " + (caret.line + 1) + ", " + (caret.col + 1));
return caret.line == (aLine - 1) && caret.col == (aCol - 1);
info("Current editor caret position: " + (cursor.line + 1) + ", " + (cursor.ch + 1));
return cursor.line == (aLine - 1) && cursor.ch == (aCol - 1);
}
function isEditorSel(aPanel, [start, end]) {
let editor = aPanel.panelWin.DebuggerView.editor;
let range = editor.getSelection();
let range = {
start: editor.getOffset(editor.getCursor("start")),
end: editor.getOffset(editor.getCursor())
};
// Source editor starts counting line and column numbers from 0.
info("Current editor selection: " + (range.start + 1) + ", " + (range.end + 1));
@ -336,12 +338,12 @@ function waitForEditorEvents(aPanel, aEventName, aEventRepeat = 1) {
let editor = aPanel.panelWin.DebuggerView.editor;
let count = 0;
editor.addEventListener(aEventName, function onEvent(...aArgs) {
editor.on(aEventName, function onEvent(...aArgs) {
info("Editor event '" + aEventName + "' fired: " + (++count) + " time(s).");
if (count == aEventRepeat) {
ok(true, "Enough '" + aEventName + "' editor events have been fired.");
editor.removeEventListener(aEventName, onEvent);
editor.off(aEventName, onEvent);
deferred.resolve.apply(deferred, aArgs);
}
});

View File

@ -32,12 +32,17 @@ browser.jar:
content/browser/devtools/codemirror/codemirror.js (sourceeditor/codemirror/codemirror.js)
content/browser/devtools/codemirror/codemirror.css (sourceeditor/codemirror/codemirror.css)
content/browser/devtools/codemirror/javascript.js (sourceeditor/codemirror/javascript.js)
content/browser/devtools/codemirror/xml.js (sourceeditor/codemirror/xml.js)
content/browser/devtools/codemirror/css.js (sourceeditor/codemirror/css.js)
content/browser/devtools/codemirror/htmlmixed.js (sourceeditor/codemirror/htmlmixed.js)
content/browser/devtools/codemirror/activeline.js (sourceeditor/codemirror/activeline.js)
content/browser/devtools/codemirror/matchbrackets.js (sourceeditor/codemirror/matchbrackets.js)
content/browser/devtools/codemirror/comment.js (sourceeditor/codemirror/comment.js)
content/browser/devtools/codemirror/searchcursor.js (sourceeditor/codemirror/search/searchcursor.js)
content/browser/devtools/codemirror/search.js (sourceeditor/codemirror/search/search.js)
content/browser/devtools/codemirror/dialog.js (sourceeditor/codemirror/dialog/dialog.js)
content/browser/devtools/codemirror/dialog.css (sourceeditor/codemirror/dialog/dialog.css)
content/browser/devtools/codemirror/mozilla.css (sourceeditor/codemirror/mozilla.css)
* content/browser/devtools/source-editor-overlay.xul (sourceeditor/source-editor-overlay.xul)
content/browser/devtools/debugger.xul (debugger/debugger.xul)
content/browser/devtools/debugger.css (debugger/debugger.css)

View File

@ -17,14 +17,13 @@ function test() {
let view = dbg.panelWin.DebuggerView;
is(view.Sources.selectedValue, data.uri, "URI is different");
is(view.editor.getCaretPosition().line, data.line - 1,
"Line is different");
is(view.editor.getCursor().line, data.line - 1, "Line is different");
// Test the case where script is already loaded.
view.editor.setCaretPosition(1);
view.editor.setCursor({ line: 1, ch: 1 });
gDevTools.showToolbox(target, "jsprofiler").then(function () {
panel.displaySource(data).then(function onOpenAgain() {
is(view.editor.getCaretPosition().line, data.line - 1,
is(view.editor.getCursor().line, data.line - 1,
"Line is different");
tearDown(tab);
});

View File

@ -102,7 +102,7 @@ function fileAImported(aStatus, aFileContent)
is(gScratchpad.getText(), gFileAContent, "the editor content is correct");
gScratchpad.editor.replaceText("new text",
gScratchpad.editor.posFromIndex(gScratchpad.getText().length));
gScratchpad.editor.getPosition(gScratchpad.getText().length));
is(gScratchpad.getText(), gFileAContent + "new text", "text updated correctly");
gScratchpad.undo();
@ -131,7 +131,7 @@ function fileBImported(aStatus, aFileContent)
"the editor content is still correct after undo");
gScratchpad.editor.replaceText("new text",
gScratchpad.editor.posFromIndex(gScratchpad.getText().length));
gScratchpad.editor.getPosition(gScratchpad.getText().length));
is(gScratchpad.getText(), gFileBContent + "new text", "text updated correctly");
gScratchpad.undo();

View File

@ -0,0 +1,40 @@
/* vim:set ts=2 sw=2 sts=2 et tw=80:
* 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/. */
(function () {
"use strict";
const WRAP_CLASS = "CodeMirror-activeline";
const BACK_CLASS = "CodeMirror-activeline-background";
CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
var prev = old && old != CodeMirror.Init;
if (val && !prev) {
updateActiveLine(cm);
cm.on("cursorActivity", updateActiveLine);
} else if (!val && prev) {
cm.off("cursorActivity", updateActiveLine);
clearActiveLine(cm);
delete cm.state.activeLine;
}
});
function clearActiveLine(cm) {
if ("activeLine" in cm.state) {
cm.removeLineClass(cm.state.activeLine, "wrap", WRAP_CLASS);
cm.removeLineClass(cm.state.activeLine, "background", BACK_CLASS);
}
}
function updateActiveLine(cm) {
var line = cm.getLineHandleVisualStart(cm.getCursor().line);
if (cm.state.activeLine == line) return;
clearActiveLine(cm);
cm.addLineClass(line, "wrap", WRAP_CLASS);
cm.addLineClass(line, "background", BACK_CLASS);
cm.state.activeLine = line;
}
})();

View File

@ -0,0 +1,623 @@
CodeMirror.defineMode("css", function(config) {
return CodeMirror.getMode(config, "text/css");
});
CodeMirror.defineMode("css-base", function(config, parserConfig) {
"use strict";
var indentUnit = config.indentUnit,
hooks = parserConfig.hooks || {},
atMediaTypes = parserConfig.atMediaTypes || {},
atMediaFeatures = parserConfig.atMediaFeatures || {},
propertyKeywords = parserConfig.propertyKeywords || {},
colorKeywords = parserConfig.colorKeywords || {},
valueKeywords = parserConfig.valueKeywords || {},
allowNested = !!parserConfig.allowNested,
type = null;
function ret(style, tp) { type = tp; return style; }
function tokenBase(stream, state) {
var ch = stream.next();
if (hooks[ch]) {
// result[0] is style and result[1] is type
var result = hooks[ch](stream, state);
if (result !== false) return result;
}
if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("def", stream.current());}
else if (ch == "=") ret(null, "compare");
else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
else if (ch == "\"" || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
else if (ch == "#") {
stream.eatWhile(/[\w\\\-]/);
return ret("atom", "hash");
}
else if (ch == "!") {
stream.match(/^\s*\w*/);
return ret("keyword", "important");
}
else if (/\d/.test(ch)) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
}
else if (ch === "-") {
if (/\d/.test(stream.peek())) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
} else if (stream.match(/^[^-]+-/)) {
return ret("meta", "meta");
}
}
else if (/[,+>*\/]/.test(ch)) {
return ret(null, "select-op");
}
else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
return ret("qualifier", "qualifier");
}
else if (ch == ":") {
return ret("operator", ch);
}
else if (/[;{}\[\]\(\)]/.test(ch)) {
return ret(null, ch);
}
else if (ch == "u" && stream.match("rl(")) {
stream.backUp(1);
state.tokenize = tokenParenthesized;
return ret("property", "variable");
}
else {
stream.eatWhile(/[\w\\\-]/);
return ret("property", "variable");
}
}
function tokenString(quote, nonInclusive) {
return function(stream, state) {
var escaped = false, ch;
while ((ch = stream.next()) != null) {
if (ch == quote && !escaped)
break;
escaped = !escaped && ch == "\\";
}
if (!escaped) {
if (nonInclusive) stream.backUp(1);
state.tokenize = tokenBase;
}
return ret("string", "string");
};
}
function tokenParenthesized(stream, state) {
stream.next(); // Must be '('
if (!stream.match(/\s*[\"\']/, false))
state.tokenize = tokenString(")", true);
else
state.tokenize = tokenBase;
return ret(null, "(");
}
return {
startState: function(base) {
return {tokenize: tokenBase,
baseIndent: base || 0,
stack: [],
lastToken: null};
},
token: function(stream, state) {
// Use these terms when applicable (see http://www.xanthir.com/blog/b4E50)
//
// rule** or **ruleset:
// A selector + braces combo, or an at-rule.
//
// declaration block:
// A sequence of declarations.
//
// declaration:
// A property + colon + value combo.
//
// property value:
// The entire value of a property.
//
// component value:
// A single piece of a property value. Like the 5px in
// text-shadow: 0 0 5px blue;. Can also refer to things that are
// multiple terms, like the 1-4 terms that make up the background-size
// portion of the background shorthand.
//
// term:
// The basic unit of author-facing CSS, like a single number (5),
// dimension (5px), string ("foo"), or function. Officially defined
// by the CSS 2.1 grammar (look for the 'term' production)
//
//
// simple selector:
// A single atomic selector, like a type selector, an attr selector, a
// class selector, etc.
//
// compound selector:
// One or more simple selectors without a combinator. div.example is
// compound, div > .example is not.
//
// complex selector:
// One or more compound selectors chained with combinators.
//
// combinator:
// The parts of selectors that express relationships. There are four
// currently - the space (descendant combinator), the greater-than
// bracket (child combinator), the plus sign (next sibling combinator),
// and the tilda (following sibling combinator).
//
// sequence of selectors:
// One or more of the named type of selector chained with commas.
state.tokenize = state.tokenize || tokenBase;
if (state.tokenize == tokenBase && stream.eatSpace()) return null;
var style = state.tokenize(stream, state);
if (style && typeof style != "string") style = ret(style[0], style[1]);
// Changing style returned based on context
var context = state.stack[state.stack.length-1];
if (style == "variable") {
if (type == "variable-definition") state.stack.push("propertyValue");
return state.lastToken = "variable-2";
} else if (style == "property") {
var word = stream.current().toLowerCase();
if (context == "propertyValue") {
if (valueKeywords.hasOwnProperty(word)) {
style = "string-2";
} else if (colorKeywords.hasOwnProperty(word)) {
style = "keyword";
} else {
style = "variable-2";
}
} else if (context == "rule") {
if (!propertyKeywords.hasOwnProperty(word)) {
style += " error";
}
} else if (context == "block") {
// if a value is present in both property, value, or color, the order
// of preference is property -> color -> value
if (propertyKeywords.hasOwnProperty(word)) {
style = "property";
} else if (colorKeywords.hasOwnProperty(word)) {
style = "keyword";
} else if (valueKeywords.hasOwnProperty(word)) {
style = "string-2";
} else {
style = "tag";
}
} else if (!context || context == "@media{") {
style = "tag";
} else if (context == "@media") {
if (atMediaTypes[stream.current()]) {
style = "attribute"; // Known attribute
} else if (/^(only|not)$/.test(word)) {
style = "keyword";
} else if (word == "and") {
style = "error"; // "and" is only allowed in @mediaType
} else if (atMediaFeatures.hasOwnProperty(word)) {
style = "error"; // Known property, should be in @mediaType(
} else {
// Unknown, expecting keyword or attribute, assuming attribute
style = "attribute error";
}
} else if (context == "@mediaType") {
if (atMediaTypes.hasOwnProperty(word)) {
style = "attribute";
} else if (word == "and") {
style = "operator";
} else if (/^(only|not)$/.test(word)) {
style = "error"; // Only allowed in @media
} else {
// Unknown attribute or property, but expecting property (preceded
// by "and"). Should be in parentheses
style = "error";
}
} else if (context == "@mediaType(") {
if (propertyKeywords.hasOwnProperty(word)) {
// do nothing, remains "property"
} else if (atMediaTypes.hasOwnProperty(word)) {
style = "error"; // Known property, should be in parentheses
} else if (word == "and") {
style = "operator";
} else if (/^(only|not)$/.test(word)) {
style = "error"; // Only allowed in @media
} else {
style += " error";
}
} else if (context == "@import") {
style = "tag";
} else {
style = "error";
}
} else if (style == "atom") {
if(!context || context == "@media{" || context == "block") {
style = "builtin";
} else if (context == "propertyValue") {
if (!/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
style += " error";
}
} else {
style = "error";
}
} else if (context == "@media" && type == "{") {
style = "error";
}
// Push/pop context stack
if (type == "{") {
if (context == "@media" || context == "@mediaType") {
state.stack[state.stack.length-1] = "@media{";
}
else {
var newContext = allowNested ? "block" : "rule";
state.stack.push(newContext);
}
}
else if (type == "}") {
if (context == "interpolation") style = "operator";
state.stack.pop();
if (context == "propertyValue") state.stack.pop();
}
else if (type == "interpolation") state.stack.push("interpolation");
else if (type == "@media") state.stack.push("@media");
else if (type == "@import") state.stack.push("@import");
else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
state.stack[state.stack.length-1] = "@mediaType";
else if (context == "@mediaType" && stream.current() == ",")
state.stack[state.stack.length-1] = "@media";
else if (type == "(") {
if (context == "@media" || context == "@mediaType") {
// Make sure @mediaType is used to avoid error on {
state.stack[state.stack.length-1] = "@mediaType";
state.stack.push("@mediaType(");
}
}
else if (type == ")") {
if (context == "propertyValue" && state.stack[state.stack.length-2] == "@mediaType(") {
// In @mediaType( without closing ; after propertyValue
state.stack.pop();
state.stack.pop();
}
else if (context == "@mediaType(") {
state.stack.pop();
}
}
else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue");
else if (context == "propertyValue" && type == ";") state.stack.pop();
else if (context == "@import" && type == ";") state.stack.pop();
return state.lastToken = style;
},
indent: function(state, textAfter) {
var n = state.stack.length;
if (/^\}/.test(textAfter))
n -= state.stack[n-1] == "propertyValue" ? 2 : 1;
return state.baseIndent + n * indentUnit;
},
electricChars: "}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
fold: "brace"
};
});
(function() {
function keySet(array) {
var keys = {};
for (var i = 0; i < array.length; ++i) {
keys[array[i]] = true;
}
return keys;
}
var atMediaTypes = keySet([
"all", "aural", "braille", "handheld", "print", "projection", "screen",
"tty", "tv", "embossed"
]);
var atMediaFeatures = keySet([
"width", "min-width", "max-width", "height", "min-height", "max-height",
"device-width", "min-device-width", "max-device-width", "device-height",
"min-device-height", "max-device-height", "aspect-ratio",
"min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
"min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
"max-color", "color-index", "min-color-index", "max-color-index",
"monochrome", "min-monochrome", "max-monochrome", "resolution",
"min-resolution", "max-resolution", "scan", "grid"
]);
var propertyKeywords = keySet([
"align-content", "align-items", "align-self", "alignment-adjust",
"alignment-baseline", "anchor-point", "animation", "animation-delay",
"animation-direction", "animation-duration", "animation-iteration-count",
"animation-name", "animation-play-state", "animation-timing-function",
"appearance", "azimuth", "backface-visibility", "background",
"background-attachment", "background-clip", "background-color",
"background-image", "background-origin", "background-position",
"background-repeat", "background-size", "baseline-shift", "binding",
"bleed", "bookmark-label", "bookmark-level", "bookmark-state",
"bookmark-target", "border", "border-bottom", "border-bottom-color",
"border-bottom-left-radius", "border-bottom-right-radius",
"border-bottom-style", "border-bottom-width", "border-collapse",
"border-color", "border-image", "border-image-outset",
"border-image-repeat", "border-image-slice", "border-image-source",
"border-image-width", "border-left", "border-left-color",
"border-left-style", "border-left-width", "border-radius", "border-right",
"border-right-color", "border-right-style", "border-right-width",
"border-spacing", "border-style", "border-top", "border-top-color",
"border-top-left-radius", "border-top-right-radius", "border-top-style",
"border-top-width", "border-width", "bottom", "box-decoration-break",
"box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
"caption-side", "clear", "clip", "color", "color-profile", "column-count",
"column-fill", "column-gap", "column-rule", "column-rule-color",
"column-rule-style", "column-rule-width", "column-span", "column-width",
"columns", "content", "counter-increment", "counter-reset", "crop", "cue",
"cue-after", "cue-before", "cursor", "direction", "display",
"dominant-baseline", "drop-initial-after-adjust",
"drop-initial-after-align", "drop-initial-before-adjust",
"drop-initial-before-align", "drop-initial-size", "drop-initial-value",
"elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
"flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
"float", "float-offset", "font", "font-feature-settings", "font-family",
"font-kerning", "font-language-override", "font-size", "font-size-adjust",
"font-stretch", "font-style", "font-synthesis", "font-variant",
"font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
"font-variant-ligatures", "font-variant-numeric", "font-variant-position",
"font-weight", "grid-cell", "grid-column", "grid-column-align",
"grid-column-sizing", "grid-column-span", "grid-columns", "grid-flow",
"grid-row", "grid-row-align", "grid-row-sizing", "grid-row-span",
"grid-rows", "grid-template", "hanging-punctuation", "height", "hyphens",
"icon", "image-orientation", "image-rendering", "image-resolution",
"inline-box-align", "justify-content", "left", "letter-spacing",
"line-break", "line-height", "line-stacking", "line-stacking-ruby",
"line-stacking-shift", "line-stacking-strategy", "list-style",
"list-style-image", "list-style-position", "list-style-type", "margin",
"margin-bottom", "margin-left", "margin-right", "margin-top",
"marker-offset", "marks", "marquee-direction", "marquee-loop",
"marquee-play-count", "marquee-speed", "marquee-style", "max-height",
"max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
"nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline",
"outline-color", "outline-offset", "outline-style", "outline-width",
"overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
"padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
"page", "page-break-after", "page-break-before", "page-break-inside",
"page-policy", "pause", "pause-after", "pause-before", "perspective",
"perspective-origin", "pitch", "pitch-range", "play-during", "position",
"presentation-level", "punctuation-trim", "quotes", "rendering-intent",
"resize", "rest", "rest-after", "rest-before", "richness", "right",
"rotation", "rotation-point", "ruby-align", "ruby-overhang",
"ruby-position", "ruby-span", "size", "speak", "speak-as", "speak-header",
"speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
"tab-size", "table-layout", "target", "target-name", "target-new",
"target-position", "text-align", "text-align-last", "text-decoration",
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
"text-decoration-style", "text-emphasis", "text-emphasis-color",
"text-emphasis-position", "text-emphasis-style", "text-height",
"text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
"text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
"text-wrap", "top", "transform", "transform-origin", "transform-style",
"transition", "transition-delay", "transition-duration",
"transition-property", "transition-timing-function", "unicode-bidi",
"vertical-align", "visibility", "voice-balance", "voice-duration",
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
"voice-volume", "volume", "white-space", "widows", "width", "word-break",
"word-spacing", "word-wrap", "z-index", "zoom",
// SVG-specific
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
"color-interpolation", "color-interpolation-filters", "color-profile",
"color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
"marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
"stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
"stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
"baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
"glyph-orientation-vertical", "kerning", "text-anchor", "writing-mode"
]);
var colorKeywords = keySet([
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
"burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
"darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
"darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
"darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
"deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
"floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
"gold", "goldenrod", "gray", "green", "greenyellow", "honeydew",
"hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
"lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
"lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
"lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
"maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
"mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
"mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
"navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
"orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
"papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
"purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon",
"sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
"slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
"whitesmoke", "yellow", "yellowgreen"
]);
var valueKeywords = keySet([
"above", "absolute", "activeborder", "activecaption", "afar",
"after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
"arabic-indic", "armenian", "asterisks", "auto", "avoid", "background",
"backwards", "baseline", "below", "bidi-override", "binary", "bengali",
"blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
"both", "bottom", "break-all", "break-word", "button", "button-bevel",
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
"cell", "center", "checkbox", "circle", "cjk-earthly-branch",
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
"col-resize", "collapse", "compact", "condensed", "contain", "content",
"content-box", "context-menu", "continuous", "copy", "cover", "crop",
"cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
"decimal-leading-zero", "default", "default-button", "destination-atop",
"destination-in", "destination-out", "destination-over", "devanagari",
"disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
"double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
"element", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
"ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
"ethiopic-halehame-gez", "ethiopic-halehame-om-et",
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et",
"ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed",
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes",
"forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
"inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
"italic", "justify", "kannada", "katakana", "katakana-iroha", "khmer",
"landscape", "lao", "large", "larger", "left", "level", "lighter",
"line-through", "linear", "lines", "list-item", "listbox", "listitem",
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
"lower-roman", "lowercase", "ltr", "malayalam", "match",
"media-controls-background", "media-current-time-display",
"media-fullscreen-button", "media-mute-button", "media-play-button",
"media-return-to-realtime-button", "media-rewind-button",
"media-seek-back-button", "media-seek-forward-button", "media-slider",
"media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
"media-volume-slider-container", "media-volume-sliderthumb", "medium",
"menu", "menulist", "menulist-button", "menulist-text",
"menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
"mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
"ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
"outside", "overlay", "overline", "padding", "padding-box", "painted",
"paused", "persian", "plus-darker", "plus-lighter", "pointer", "portrait",
"pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
"radio", "read-only", "read-write", "read-write-plaintext-only", "relative",
"repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
"ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
"s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
"searchfield-cancel-button", "searchfield-decoration",
"searchfield-results-button", "searchfield-results-decoration",
"semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
"single", "skip-white-space", "slide", "slider-horizontal",
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "solid", "somali",
"source-atop", "source-in", "source-out", "source-over", "space", "square",
"square-button", "start", "static", "status-bar", "stretch", "stroke",
"sub", "subpixel-antialiased", "super", "sw-resize", "table",
"table-caption", "table-cell", "table-column", "table-column-group",
"table-footer-group", "table-header-group", "table-row", "table-row-group",
"telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
"thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
"threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
"transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
"vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
"window", "windowframe", "windowtext", "x-large", "x-small", "xor",
"xx-large", "xx-small"
]);
function tokenCComment(stream, state) {
var maybeEnd = false, ch;
while ((ch = stream.next()) != null) {
if (maybeEnd && ch == "/") {
state.tokenize = null;
break;
}
maybeEnd = (ch == "*");
}
return ["comment", "comment"];
}
CodeMirror.defineMIME("text/css", {
atMediaTypes: atMediaTypes,
atMediaFeatures: atMediaFeatures,
propertyKeywords: propertyKeywords,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
hooks: {
"<": function(stream, state) {
function tokenSGMLComment(stream, state) {
var dashes = 0, ch;
while ((ch = stream.next()) != null) {
if (dashes >= 2 && ch == ">") {
state.tokenize = null;
break;
}
dashes = (ch == "-") ? dashes + 1 : 0;
}
return ["comment", "comment"];
}
if (stream.eat("!")) {
state.tokenize = tokenSGMLComment;
return tokenSGMLComment(stream, state);
}
},
"/": function(stream, state) {
if (stream.eat("*")) {
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
}
return false;
}
},
name: "css-base"
});
CodeMirror.defineMIME("text/x-scss", {
atMediaTypes: atMediaTypes,
atMediaFeatures: atMediaFeatures,
propertyKeywords: propertyKeywords,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
allowNested: true,
hooks: {
"$": function(stream) {
stream.match(/^[\w-]+/);
if (stream.peek() == ":") {
return ["variable", "variable-definition"];
}
return ["variable", "variable"];
},
"/": function(stream, state) {
if (stream.eat("/")) {
stream.skipToEnd();
return ["comment", "comment"];
} else if (stream.eat("*")) {
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
} else {
return ["operator", "operator"];
}
},
"#": function(stream) {
if (stream.eat("{")) {
return ["operator", "interpolation"];
} else {
stream.eatWhile(/[\w\\\-]/);
return ["atom", "hash"];
}
}
},
name: "css-base"
});
})();

View File

@ -0,0 +1,104 @@
CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
var cssMode = CodeMirror.getMode(config, "css");
var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes;
scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,
mode: CodeMirror.getMode(config, "javascript")});
if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) {
var conf = scriptTypesConf[i];
scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)});
}
scriptTypes.push({matches: /./,
mode: CodeMirror.getMode(config, "text/plain")});
function html(stream, state) {
var tagName = state.htmlState.tagName;
var style = htmlMode.token(stream, state.htmlState);
if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") {
// Script block: mode to change to depends on type attribute
var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i);
scriptType = scriptType ? scriptType[1] : "";
if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1);
for (var i = 0; i < scriptTypes.length; ++i) {
var tp = scriptTypes[i];
if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) {
if (tp.mode) {
state.token = script;
state.localMode = tp.mode;
state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, ""));
}
break;
}
}
} else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") {
state.token = css;
state.localMode = cssMode;
state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
}
return style;
}
function maybeBackup(stream, pat, style) {
var cur = stream.current();
var close = cur.search(pat), m;
if (close > -1) stream.backUp(cur.length - close);
else if (m = cur.match(/<\/?$/)) {
stream.backUp(cur.length);
if (!stream.match(pat, false)) stream.match(cur[0]);
}
return style;
}
function script(stream, state) {
if (stream.match(/^<\/\s*script\s*>/i, false)) {
state.token = html;
state.localState = state.localMode = null;
return html(stream, state);
}
return maybeBackup(stream, /<\/\s*script\s*>/,
state.localMode.token(stream, state.localState));
}
function css(stream, state) {
if (stream.match(/^<\/\s*style\s*>/i, false)) {
state.token = html;
state.localState = state.localMode = null;
return html(stream, state);
}
return maybeBackup(stream, /<\/\s*style\s*>/,
cssMode.token(stream, state.localState));
}
return {
startState: function() {
var state = htmlMode.startState();
return {token: html, localMode: null, localState: null, htmlState: state};
},
copyState: function(state) {
if (state.localState)
var local = CodeMirror.copyState(state.localMode, state.localState);
return {token: state.token, localMode: state.localMode, localState: local,
htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
},
token: function(stream, state) {
return state.token(stream, state);
},
indent: function(state, textAfter) {
if (!state.localMode || /^\s*<\//.test(textAfter))
return htmlMode.indent(state.htmlState, textAfter);
else if (state.localMode.indent)
return state.localMode.indent(state.localState, textAfter);
else
return CodeMirror.Pass;
},
electricChars: "/{}:",
innerMode: function(state) {
return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
}
};
}, "xml", "javascript", "css");
CodeMirror.defineMIME("text/html", "htmlmixed");

View File

@ -0,0 +1,30 @@
.breakpoints {
width: 16px;
}
.breakpoint, .debugLocation, .breakpoint-debugLocation {
display: inline-block;
margin-left: 5px;
width: 14px;
height: 14px;
background-repeat: no-repeat;
background-position: center center;
background-size: 12px;
}
.breakpoint {
background-image: url("chrome://browser/skin/devtools/orion-breakpoint.png");
}
.debugLocation {
background-image: url("chrome://browser/skin/devtools/orion-debug-location.png");
}
.breakpoint.debugLocation {
background-image: url("chrome://browser/skin/devtools/orion-debug-location.png"),
url("chrome://browser/skin/devtools/orion-breakpoint.png");
}
.CodeMirror-activeline-background {
background: #e8f2ff;
}

View File

@ -0,0 +1,341 @@
CodeMirror.defineMode("xml", function(config, parserConfig) {
var indentUnit = config.indentUnit;
var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag || true;
var Kludges = parserConfig.htmlMode ? {
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
'track': true, 'wbr': true},
implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
'th': true, 'tr': true},
contextGrabbers: {
'dd': {'dd': true, 'dt': true},
'dt': {'dd': true, 'dt': true},
'li': {'li': true},
'option': {'option': true, 'optgroup': true},
'optgroup': {'optgroup': true},
'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
'rp': {'rp': true, 'rt': true},
'rt': {'rp': true, 'rt': true},
'tbody': {'tbody': true, 'tfoot': true},
'td': {'td': true, 'th': true},
'tfoot': {'tbody': true},
'th': {'td': true, 'th': true},
'thead': {'tbody': true, 'tfoot': true},
'tr': {'tr': true}
},
doNotIndent: {"pre": true},
allowUnquoted: true,
allowMissing: true
} : {
autoSelfClosers: {},
implicitlyClosed: {},
contextGrabbers: {},
doNotIndent: {},
allowUnquoted: false,
allowMissing: false
};
var alignCDATA = parserConfig.alignCDATA;
// Return variables for tokenizers
var tagName, type;
function inText(stream, state) {
function chain(parser) {
state.tokenize = parser;
return parser(stream, state);
}
var ch = stream.next();
if (ch == "<") {
if (stream.eat("!")) {
if (stream.eat("[")) {
if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
else return null;
} else if (stream.match("--")) {
return chain(inBlock("comment", "-->"));
} else if (stream.match("DOCTYPE", true, true)) {
stream.eatWhile(/[\w\._\-]/);
return chain(doctype(1));
} else {
return null;
}
} else if (stream.eat("?")) {
stream.eatWhile(/[\w\._\-]/);
state.tokenize = inBlock("meta", "?>");
return "meta";
} else {
var isClose = stream.eat("/");
tagName = "";
var c;
while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
if (!tagName) return "error";
type = isClose ? "closeTag" : "openTag";
state.tokenize = inTag;
return "tag";
}
} else if (ch == "&") {
var ok;
if (stream.eat("#")) {
if (stream.eat("x")) {
ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
} else {
ok = stream.eatWhile(/[\d]/) && stream.eat(";");
}
} else {
ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
}
return ok ? "atom" : "error";
} else {
stream.eatWhile(/[^&<]/);
return null;
}
}
function inTag(stream, state) {
var ch = stream.next();
if (ch == ">" || (ch == "/" && stream.eat(">"))) {
state.tokenize = inText;
type = ch == ">" ? "endTag" : "selfcloseTag";
return "tag";
} else if (ch == "=") {
type = "equals";
return null;
} else if (ch == "<") {
return "error";
} else if (/[\'\"]/.test(ch)) {
state.tokenize = inAttribute(ch);
state.stringStartCol = stream.column();
return state.tokenize(stream, state);
} else {
stream.eatWhile(/[^\s\u00a0=<>\"\']/);
return "word";
}
}
function inAttribute(quote) {
var closure = function(stream, state) {
while (!stream.eol()) {
if (stream.next() == quote) {
state.tokenize = inTag;
break;
}
}
return "string";
};
closure.isInAttribute = true;
return closure;
}
function inBlock(style, terminator) {
return function(stream, state) {
while (!stream.eol()) {
if (stream.match(terminator)) {
state.tokenize = inText;
break;
}
stream.next();
}
return style;
};
}
function doctype(depth) {
return function(stream, state) {
var ch;
while ((ch = stream.next()) != null) {
if (ch == "<") {
state.tokenize = doctype(depth + 1);
return state.tokenize(stream, state);
} else if (ch == ">") {
if (depth == 1) {
state.tokenize = inText;
break;
} else {
state.tokenize = doctype(depth - 1);
return state.tokenize(stream, state);
}
}
}
return "meta";
};
}
var curState, curStream, setStyle;
function pass() {
for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
}
function cont() {
pass.apply(null, arguments);
return true;
}
function pushContext(tagName, startOfLine) {
var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
curState.context = {
prev: curState.context,
tagName: tagName,
indent: curState.indented,
startOfLine: startOfLine,
noIndent: noIndent
};
}
function popContext() {
if (curState.context) curState.context = curState.context.prev;
}
function element(type) {
if (type == "openTag") {
curState.tagName = tagName;
curState.tagStart = curStream.column();
return cont(attributes, endtag(curState.startOfLine));
} else if (type == "closeTag") {
var err = false;
if (curState.context) {
if (curState.context.tagName != tagName) {
if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
popContext();
}
err = !curState.context || curState.context.tagName != tagName;
}
} else {
err = true;
}
if (err) setStyle = "error";
return cont(endclosetag(err));
}
return cont();
}
function endtag(startOfLine) {
return function(type) {
var tagName = curState.tagName;
curState.tagName = curState.tagStart = null;
if (type == "selfcloseTag" ||
(type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase()))) {
maybePopContext(tagName.toLowerCase());
return cont();
}
if (type == "endTag") {
maybePopContext(tagName.toLowerCase());
pushContext(tagName, startOfLine);
return cont();
}
return cont();
};
}
function endclosetag(err) {
return function(type) {
if (err) setStyle = "error";
if (type == "endTag") { popContext(); return cont(); }
setStyle = "error";
return cont(arguments.callee);
};
}
function maybePopContext(nextTagName) {
var parentTagName;
while (true) {
if (!curState.context) {
return;
}
parentTagName = curState.context.tagName.toLowerCase();
if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
!Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
return;
}
popContext();
}
}
function attributes(type) {
if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
if (type == "endTag" || type == "selfcloseTag") return pass();
setStyle = "error";
return cont(attributes);
}
function attribute(type) {
if (type == "equals") return cont(attvalue, attributes);
if (!Kludges.allowMissing) setStyle = "error";
else if (type == "word") setStyle = "attribute";
return (type == "endTag" || type == "selfcloseTag") ? pass() : cont();
}
function attvalue(type) {
if (type == "string") return cont(attvaluemaybe);
if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
setStyle = "error";
return (type == "endTag" || type == "selfCloseTag") ? pass() : cont();
}
function attvaluemaybe(type) {
if (type == "string") return cont(attvaluemaybe);
else return pass();
}
return {
startState: function() {
return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, tagStart: null, context: null};
},
token: function(stream, state) {
if (!state.tagName && stream.sol()) {
state.startOfLine = true;
state.indented = stream.indentation();
}
if (stream.eatSpace()) return null;
setStyle = type = tagName = null;
var style = state.tokenize(stream, state);
state.type = type;
if ((style || type) && style != "comment") {
curState = state; curStream = stream;
while (true) {
var comb = state.cc.pop() || element;
if (comb(type || style)) break;
}
}
state.startOfLine = false;
return setStyle || style;
},
indent: function(state, textAfter, fullLine) {
var context = state.context;
// Indent multi-line strings (e.g. css).
if (state.tokenize.isInAttribute) {
return state.stringStartCol + 1;
}
if ((state.tokenize != inTag && state.tokenize != inText) ||
context && context.noIndent)
return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
// Indent the starts of attribute names.
if (state.tagName) {
if (multilineTagIndentPastTag)
return state.tagStart + state.tagName.length + 2;
else
return state.tagStart + indentUnit * multilineTagIndentFactor;
}
if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
if (context && /^<\//.test(textAfter))
context = context.prev;
while (context && !context.startOfLine)
context = context.prev;
if (context) return context.indent + indentUnit;
else return 0;
},
electricChars: "/",
blockCommentStart: "<!--",
blockCommentEnd: "-->",
configuration: parserConfig.htmlMode ? "html" : "xml",
helperType: parserConfig.htmlMode ? "html" : "xml"
};
});
CodeMirror.defineMIME("text/xml", "xml");
CodeMirror.defineMIME("application/xml", "xml");
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});

View File

@ -0,0 +1,267 @@
/* 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 dbginfo = new WeakMap();
// Private functions
/**
* Adds a marker to the breakpoints gutter.
* Type should be either a 'breakpoint' or a 'debugLocation'.
*/
function addMarker(cm, line, type) {
let info = cm.lineInfo(line);
if (info.gutterMarkers)
return void info.gutterMarkers.breakpoints.classList.add(type);
let mark = cm.getWrapperElement().ownerDocument.createElement("div");
mark.className = type;
mark.innerHTML = "";
cm.setGutterMarker(info.line, "breakpoints", mark);
}
/**
* Removes a marker from the breakpoints gutter.
* Type should be either a 'breakpoint' or a 'debugLocation'.
*/
function removeMarker(cm, line, type) {
let info = cm.lineInfo(line);
if (!info || !info.gutterMarkers)
return;
info.gutterMarkers.breakpoints.classList.remove(type);
}
// These functions implement search within the debugger. Since
// search in the debugger is different from other components,
// we can't use search.js CodeMirror addon. This is a slightly
// modified version of that addon. Depends on searchcursor.js.
function SearchState() {
this.posFrom = this.posTo = this.query = null;
}
function getSearchState(cm) {
return cm.state.search || (cm.state.search = new SearchState());
}
function getSearchCursor(cm, query, pos) {
// If the query string is all lowercase, do a case insensitive search.
return cm.getSearchCursor(query, pos,
typeof query == "string" && query == query.toLowerCase());
}
/**
* If there's a saved search, selects the next results.
* Otherwise, creates a new search and selects the first
* result.
*/
function doSearch(cm, rev, query) {
let state = getSearchState(cm);
if (state.query)
return searchNext(cm, rev);
cm.operation(function () {
if (state.query) return;
state.query = query;
state.posFrom = state.posTo = { line: 0, ch: 0 };
searchNext(cm, rev);
});
}
/**
* Selects the next result of a saved search.
*/
function searchNext(cm, rev) {
cm.operation(function () {
let state = getSearchState(cm)
let cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
if (!cursor.find(rev)) {
cursor = getSearchCursor(cm, state.query, rev ?
{ line: cm.lastLine(), ch: null } : { line: cm.firstLine(), ch: 0 });
if (!cursor.find(rev))
return;
}
cm.setSelection(cursor.from(), cursor.to());
state.posFrom = cursor.from();
state.posTo = cursor.to();
});
}
/**
* Clears the currently saved search.
*/
function clearSearch(cm) {
let state = getSearchState(cm);
if (!state.query)
return;
state.query = null;
}
// Exported functions
/**
* This function is called whenever Editor is extended with functions
* from this module. See Editor.extend for more info.
*/
function initialize(ctx) {
let { ed } = ctx;
dbginfo.set(ed, {
breakpoints: {},
debugLocation: null
});
}
/**
* True if editor has a visual breakpoint at that line, false
* otherwise.
*/
function hasBreakpoint(ctx, line) {
let { cm } = ctx;
let markers = cm.lineInfo(line).gutterMarkers;
return markers != null &&
markers.breakpoints.classList.contains("breakpoint");
}
/**
* Adds a visual breakpoint for a specified line. Third
* parameter 'cond' can hold any object.
*
* After adding a breakpoint, this function makes Editor to
* emit a breakpointAdded event.
*/
function addBreakpoint(ctx, line, cond) {
if (hasBreakpoint(ctx, line))
return;
let { ed, cm } = ctx;
let meta = dbginfo.get(ed);
let info = cm.lineInfo(line);
addMarker(cm, line, "breakpoint");
meta.breakpoints[line] = { condition: cond };
info.handle.on("delete", function onDelete() {
info.handle.off("delete", onDelete);
meta.breakpoints[info.line] = null;
});
ed.emit("breakpointAdded", line);
}
/**
* Removes a visual breakpoint from a specified line and
* makes Editor to emit a breakpointRemoved event.
*/
function removeBreakpoint(ctx, line) {
if (!hasBreakpoint(ctx, line))
return;
let { ed, cm } = ctx;
let meta = dbginfo.get(ed);
let info = cm.lineInfo(line);
meta.breakpoints[info.line] = null;
removeMarker(cm, info.line, "breakpoint");
ed.emit("breakpointRemoved", line);
}
/**
* Returns a list of all breakpoints in the current Editor.
*/
function getBreakpoints(ctx) {
let { ed } = ctx;
let meta = dbginfo.get(ed);
return Object.keys(meta.breakpoints).reduce((acc, line) => {
if (meta.breakpoints[line] != null)
acc.push({ line: line, condition: meta.breakpoints[line].condition });
return acc;
}, []);
}
/**
* Saves a debug location information and adds a visual anchor to
* the breakpoints gutter. This is used by the debugger UI to
* display the line on which the Debugger is currently paused.
*/
function setDebugLocation(ctx, line) {
let { ed, cm } = ctx;
let meta = dbginfo.get(ed);
meta.debugLocation = line;
addMarker(cm, line, "debugLocation");
}
/**
* Returns a line number that corresponds to the current debug
* location.
*/
function getDebugLocation(ctx) {
let { ed } = ctx;
let meta = dbginfo.get(ed);
return meta.debugLocation;
}
/**
* Clears the debug location. Clearing the debug location
* also removes a visual anchor from the breakpoints gutter.
*/
function clearDebugLocation(ctx) {
let { ed, cm } = ctx;
let meta = dbginfo.get(ed);
if (meta.debugLocation != null) {
removeMarker(cm, meta.debugLocation, "debugLocation");
meta.debugLocation = null;
}
}
/**
* Starts a new search.
*/
function find(ctx, query) {
let { cm } = ctx;
clearSearch(cm);
doSearch(cm, false, query);
}
/**
* Finds the next item based on the currently saved search.
*/
function findNext(ctx, query) {
let { cm } = ctx;
doSearch(cm, false, query);
}
/**
* Finds the previous item based on the currently saved search.
*/
function findPrev(ctx, query) {
let { cm } = ctx;
doSearch(cm, true, query);
}
// Export functions
[
initialize, hasBreakpoint, addBreakpoint, removeBreakpoint,
getBreakpoints, setDebugLocation, getDebugLocation,
clearDebugLocation, find, findNext, findPrev
].forEach(function (func) { module.exports[func.name] = func; });

View File

@ -24,7 +24,8 @@ const L10N = Services.strings.createBundle(L10N_BUNDLE);
const CM_STYLES = [
"chrome://browser/content/devtools/codemirror/codemirror.css",
"chrome://browser/content/devtools/codemirror/dialog.css"
"chrome://browser/content/devtools/codemirror/dialog.css",
"chrome://browser/content/devtools/codemirror/mozilla.css"
];
const CM_SCRIPTS = [
@ -33,7 +34,12 @@ const CM_SCRIPTS = [
"chrome://browser/content/devtools/codemirror/searchcursor.js",
"chrome://browser/content/devtools/codemirror/search.js",
"chrome://browser/content/devtools/codemirror/matchbrackets.js",
"chrome://browser/content/devtools/codemirror/comment.js"
"chrome://browser/content/devtools/codemirror/comment.js",
"chrome://browser/content/devtools/codemirror/javascript.js",
"chrome://browser/content/devtools/codemirror/xml.js",
"chrome://browser/content/devtools/codemirror/css.js",
"chrome://browser/content/devtools/codemirror/htmlmixed.js",
"chrome://browser/content/devtools/codemirror/activeline.js"
];
const CM_IFRAME =
@ -62,8 +68,9 @@ const CM_MAPPING = [
"undo",
"redo",
"clearHistory",
"posFromIndex",
"openDialog"
"openDialog",
"cursorCoords",
"lineCount"
];
const CM_JUMP_DIALOG = [
@ -75,7 +82,9 @@ const editors = new WeakMap();
Editor.modes = {
text: { name: "text" },
js: { name: "javascript", url: "chrome://browser/content/devtools/codemirror/javascript.js" }
js: { name: "javascript" },
html: { name: "htmlmixed" },
css: { name: "css" }
};
function ctrl(k) {
@ -109,14 +118,15 @@ function Editor(config) {
this.version = null;
this.config = {
value: "",
mode: Editor.modes.text,
indentUnit: tabSize,
tabSize: tabSize,
contextMenu: null,
matchBrackets: true,
extraKeys: {},
indentWithTabs: useTabs,
value: "",
mode: Editor.modes.text,
indentUnit: tabSize,
tabSize: tabSize,
contextMenu: null,
matchBrackets: true,
extraKeys: {},
indentWithTabs: useTabs,
styleActiveLine: true
};
// Overwrite default config with user-provided, if needed.
@ -151,8 +161,9 @@ function Editor(config) {
}
Editor.prototype = {
container: null,
version: null,
config: null,
config: null,
/**
* Appends the current Editor instance to the element specified by
@ -174,17 +185,13 @@ Editor.prototype = {
let onLoad = () => {
// Once the iframe is loaded, we can inject CodeMirror
// and its dependencies into its DOM.
env.removeEventListener("load", onLoad, true);
let win = env.contentWindow.wrappedJSObject;
CM_SCRIPTS.forEach((url) =>
Services.scriptloader.loadSubScript(url, win, "utf8"));
// Plain text mode doesn't need any additional files,
// all other modes (js, html, etc.) do.
if (this.config.mode.name !== "text")
Services.scriptloader.loadSubScript(this.config.mode.url, win, "utf8");
// Create a CodeMirror instance add support for context menus and
// overwrite the default controller (otherwise items in the top and
// context menus won't work).
@ -192,12 +199,17 @@ Editor.prototype = {
cm = win.CodeMirror(win.document.body, this.config);
cm.getWrapperElement().addEventListener("contextmenu", (ev) => {
ev.preventDefault();
this.emit("contextMenu");
this.showContextMenu(doc, ev.screenX, ev.screenY);
}, false);
cm.on("change", () => this.emit("change"));
cm.on("gutterClick", (cm, line) => this.emit("gutterClick", line));
cm.on("cursorActivity", (cm) => this.emit("cursorActivity"));
doc.defaultView.controllers.insertControllerAt(0, controller(this, doc.defaultView));
this.container = env;
editors.set(this, cm);
def.resolve();
};
@ -252,11 +264,13 @@ Editor.prototype = {
},
/**
* Returns text from the text area.
* Returns text from the text area. If line argument is provided
* the method returns only that line.
*/
getText: function () {
getText: function (line) {
let cm = editors.get(this);
return cm.getValue();
return line == null ?
cm.getValue() : (cm.lineInfo(line) ? cm.lineInfo(line).text : "");
},
/**
@ -268,6 +282,32 @@ Editor.prototype = {
cm.setValue(value);
},
/**
* Changes the value of a currently used highlighting mode.
* See Editor.modes for the list of all suppoert modes.
*/
setMode: function (value) {
let cm = editors.get(this);
cm.setOption("mode", value);
},
/**
* Returns the currently active highlighting mode.
* See Editor.modes for the list of all suppoert modes.
*/
getMode: function () {
let cm = editors.get(this);
return cm.getOption("mode");
},
/**
* True if the editor is in the read-only mode, false otherwise.
*/
isReadOnly: function () {
let cm = editors.get(this);
return cm.getOption("readOnly");
},
/**
* Replaces contents of a text area within the from/to {line, ch}
* range. If neither from nor to arguments are provided works
@ -340,8 +380,59 @@ Editor.prototype = {
this.setCursor({ line: line - 1, ch: 0 }));
},
/**
* Returns a {line, ch} object that corresponds to the
* left, top coordinates.
*/
getPositionFromCoords: function (left, top) {
let cm = editors.get(this);
return cm.coordsChar({ left: left, top: top });
},
/**
* Extends the current selection to the position specified
* by the provided {line, ch} object.
*/
extendSelection: function (pos) {
let cm = editors.get(this);
let cursor = cm.indexFromPos(cm.getCursor());
let anchor = cm.posFromIndex(cursor + pos.start);
let head = cm.posFromIndex(cursor + pos.start + pos.length);
cm.setSelection(anchor, head);
},
/**
* Extends an instance of the Editor object with additional
* functions. Each function will be called with context as
* the first argument. Context is a {ed, cm} object where
* 'ed' is an instance of the Editor object and 'cm' is an
* instance of the CodeMirror object. Example:
*
* function hello(ctx, name) {
* let { cm, ed } = ctx;
* cm; // CodeMirror instance
* ed; // Editor instance
* name; // 'Mozilla'
* }
*
* editor.extend({ hello: hello });
* editor.hello('Mozilla');
*/
extend: function (funcs) {
Object.keys(funcs).forEach((name) => {
let cm = editors.get(this);
let ctx = { ed: this, cm: cm };
if (name === "initialize")
return void funcs[name](ctx);
this[name] = funcs[name].bind(null, ctx);
});
},
destroy: function () {
this.config = null;
this.container = null;
this.config = null;
this.version = null;
this.emit("destroy");
}
@ -365,8 +456,6 @@ CM_MAPPING.forEach(function (name) {
function controller(ed, view) {
return {
supportsCommand: function (cmd) {
let cm = editors.get(ed);
switch (cmd) {
case "cmd_find":
case "cmd_findAgain":

View File

@ -9,6 +9,7 @@ TEST_DIRS += ['test']
JS_MODULES_PATH = 'modules/devtools/sourceeditor'
EXTRA_JS_MODULES += [
'debugger.js',
'editor.js',
'source-editor-orion.jsm',
'source-editor-ui.jsm',

View File

@ -101,7 +101,7 @@ function checkCorrectLine(aCallback)
{
let debuggerView = dbg.panelWin.DebuggerView;
if (debuggerView.editor &&
debuggerView.editor.getCaretPosition().line == line - 1) {
debuggerView.editor.getCursor().line == line - 1) {
return true;
}
return false;

View File

@ -354,6 +354,8 @@
@BINPATH@/browser/components/DownloadsStartup.js
@BINPATH@/browser/components/DownloadsUI.js
@BINPATH@/browser/components/BrowserPlaces.manifest
@BINPATH@/browser/components/devtools-clhandler.manifest
@BINPATH@/browser/components/devtools-clhandler.js
@BINPATH@/components/Downloads.manifest
@BINPATH@/components/DownloadLegacy.js
@BINPATH@/components/BrowserPageThumbs.manifest

View File

@ -91,6 +91,18 @@
</body>
</method>
<method name="selectNone">
<body>
<![CDATA[
let selectedCount = this.selectedItems.length;
this.clearSelection();
if (selectedCount && "single" != this.getAttribute("seltype")) {
this._fireEvent("selectionchange");
}
]]>
</body>
</method>
<method name="handleItemClick">
<parameter name="aItem"/>
<parameter name="aEvent"/>
@ -116,7 +128,7 @@
<parameter name="aEvent"/>
<body>
<![CDATA[
if (!this.isBound || this.suppressOnSelect)
if (!this.isBound || this.noContext)
return;
// we'll republish this as a selectionchange event on the grid
aEvent.stopPropagation();
@ -192,7 +204,7 @@
let selected = this.getItemAtIndex(val);
this.selectItem(selected);
} else {
this.clearSelection();
this.selectNone();
}
]]>
</setter>
@ -610,6 +622,9 @@
<property name="suppressOnSelect"
onget="return this.getAttribute('suppressonselect') == 'true';"
onset="this.setAttribute('suppressonselect', val);"/>
<property name="noContext"
onget="return this.hasAttribute('nocontext');"
onset="if (val) this.setAttribute('nocontext', true); else this.removeAttribute('nocontext');"/>
<property name="crossSlideBoundary"
onget="return this.hasAttribute('crossslideboundary')? this.getAttribute('crossslideboundary') : Infinity;"/>
@ -627,7 +642,7 @@
this.controller.gridBoundCallback();
// set up cross-slide gesture handling for multiple-selection grids
if ("undefined" !== typeof CrossSlide && "multiple" == this.getAttribute("seltype")) {
if ("undefined" !== typeof CrossSlide && !this.noContext) {
this._xslideHandler = new CrossSlide.Handler(this, {
REARRANGESTART: this.crossSlideBoundary
});
@ -836,7 +851,7 @@
// which directs us to do something to the selected tiles
switch (event.action) {
case "clear":
this.clearSelection();
this.selectNone();
break;
default:
if (this.controller && this.controller.doActionOnSelectedTiles) {
@ -896,7 +911,7 @@
</handler>
<handler event="MozCrossSlideSelect">
<![CDATA[
if (this.suppressOnSelect)
if (this.noContext)
return;
this.toggleItemSelection(event.target);
]]>

View File

@ -505,13 +505,13 @@
<xul:label class="meta-section-title"
value="&autocompleteResultsHeader.label;"/>
<richgrid anonid="results" rows="3" flex="1"
seltype="single" deferlayout="true"/>
seltype="single" nocontext="true" deferlayout="true"/>
</xul:vbox>
<xul:vbox class="meta-section" flex="1">
<xul:label anonid="searches-header" class="meta-section-title"/>
<richgrid anonid="searches" rows="3" flex="1"
seltype="single" deferlayout="true"/>
seltype="single" nocontext="true" deferlayout="true"/>
</xul:vbox>
</content>
@ -519,7 +519,6 @@
<constructor>
<![CDATA[
this.hidden = true;
Services.obs.addObserver(this, "browser-search-engine-modified", false);
this._results.controller = this;

View File

@ -378,13 +378,6 @@ MenuPopup.prototype = {
let screenWidth = ContentAreaObserver.width;
let screenHeight = ContentAreaObserver.height;
// Add padding on the side of the menu per the user's hand preference
let leftHand =
Services.metro.handPreference == Ci.nsIWinMetroUtils.handPreferenceLeft;
if (aSource && aSource == Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH) {
this.commands.setAttribute("left-hand", leftHand);
}
if (aPositionOptions.rightAligned)
aX -= width;

View File

@ -114,15 +114,54 @@ gTests.push({
yield restoreViewstate();
}
});
gTests.push({
desc: "Test tile selection is cleared and disabled",
setUp: function() {
BookmarksTestHelper.setup();
HistoryTestHelper.setup();
showStartUI();
},
run: function() {
// minimal event mocking to trigger context-click handlers
function makeMockEvent(item) {
return {
stopPropagation: function() {},
target: item
};
}
let startWin = Browser.selectedBrowser.contentWindow;
// make sure the bookmarks grid is showing
startWin.StartUI.onNarrowTitleClick("start-bookmarks");
let bookmarksGrid = startWin.document.querySelector("#start-bookmarks-grid");
// sanity check
ok(bookmarksGrid, "matched bookmarks grid");
ok(bookmarksGrid.children[0], "bookmarks grid has items");
// select a tile (balancing implementation leakage with test simplicity)
let mockEvent = makeMockEvent(bookmarksGrid.children[0]);
bookmarksGrid.handleItemContextMenu(bookmarksGrid.children[0], mockEvent);
// check tile was selected
is(bookmarksGrid.selectedItems.length, 1, "Tile got selected in landscape view");
// switch to snapped view
yield setSnappedViewstate();
is(bookmarksGrid.selectedItems.length, 0, "grid items selection cleared in snapped view");
// attempt to select a tile in snapped view
mockEvent = makeMockEvent(bookmarksGrid.children[0]);
bookmarksGrid.handleItemContextMenu(bookmarksGrid.children[0], mockEvent);
is(bookmarksGrid.selectedItems.length, 0, "no grid item selections possible in snapped view");
},
tearDown: function() {
BookmarksTestHelper.restore();
HistoryTestHelper.restore();
yield restoreViewstate();
}
});
gTests.push({
desc: "Navbar contextual buttons are not shown in snapped",
setUp: setUpSnapped,
run: function() {
let toolbarContextual = document.getElementById("toolbar-contextual");
let visibility = getComputedStyle(toolbarContextual).getPropertyValue("visibility");
ok(visibility === "collapse" || visibility === "hidden", "Contextual buttons not shown in navbar");
},
tearDown: restoreViewstate

View File

@ -8,13 +8,10 @@
<?xml-stylesheet href="chrome://browser/skin/browser.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/browser.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/tiles.css" type="text/css"?>
<!DOCTYPE window []>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<vbox id="alayout">
<richgrid id="grid_layout" seltype="single" flex="1">
<richgrid id="grid_layout" seltype="single" nocontext="true" flex="1">
</richgrid>
</vbox>
<vbox>
@ -22,7 +19,7 @@
</vbox>
<vbox style="height:600px">
<hbox>
<richgrid id="clearGrid" seltype="single" flex="1" rows="2">
<richgrid id="clearGrid" seltype="single" nocontext="true" flex="1" rows="2">
<richgriditem value="about:blank" id="clearGrid_item1" label="First item"/>
<richgriditem value="about:blank" id="clearGrid_item2" label="2nd item"/>
<richgriditem value="about:blank" id="clearGrid_item1" label="First item"/>

View File

@ -355,13 +355,6 @@ gTests.push({
ok(grid.items[1].getAttribute("selected"), "Item selected attribute is truthy after grid.selectItem");
ok(grid.selectedItems.length, "There are selectedItems after grid.selectItem");
// clearSelection
grid.selectItem(grid.items[0]);
grid.selectItem(grid.items[1]);
grid.clearSelection();
is(grid.selectedItems.length, 0, "Nothing selected when we clearSelection");
is(grid.selectedIndex, -1, "selectedIndex resets after clearSelection");
// select events
// in seltype=single mode, select is like the default action for the tile
// (think <a>, not <select multiple>)
@ -369,9 +362,18 @@ gTests.push({
handleEvent: function(aEvent) {}
};
let handlerStub = stubMethod(handler, "handleEvent");
grid.items[1].selected = true;
doc.defaultView.addEventListener("select", handler, false);
info("select listener added");
// clearSelection
grid.clearSelection();
is(grid.selectedItems.length, 0, "Nothing selected when we clearSelection");
is(grid.selectedIndex, -1, "selectedIndex resets after clearSelection");
is(handlerStub.callCount, 0, "clearSelection should not fire a selectionchange event");
info("calling selectItem, currently it is:" + grid.items[0].selected);
// Note: A richgrid in seltype=single mode fires "select" events from selectItem
grid.selectItem(grid.items[0]);
@ -412,14 +414,6 @@ gTests.push({
grid.toggleItemSelection(grid.items[1]);
is(grid.selectedItems.length, 0, "Nothing selected when we toggleItemSelection again");
// clearSelection
grid.items[0].selected=true;
grid.items[1].selected=true;
is(grid.selectedItems.length, 2, "Both items are selected before calling clearSelection");
grid.clearSelection();
is(grid.selectedItems.length, 0, "Nothing selected when we clearSelection");
ok(!(grid.items[0].selected || grid.items[1].selected), "selected properties all falsy when we clearSelection");
// selectionchange events
// in seltype=multiple mode, we track selected state on all items
// (think <select multiple> not <a>)
@ -430,6 +424,15 @@ gTests.push({
doc.defaultView.addEventListener("selectionchange", handler, false);
info("selectionchange listener added");
// clearSelection
grid.items[0].selected=true;
grid.items[1].selected=true;
is(grid.selectedItems.length, 2, "Both items are selected before calling clearSelection");
grid.clearSelection();
is(grid.selectedItems.length, 0, "Nothing selected when we clearSelection");
ok(!(grid.items[0].selected || grid.items[1].selected), "selected properties all falsy when we clearSelection");
is(handlerStub.callCount, 0, "clearSelection should not fire a selectionchange event");
info("calling toggleItemSelection, currently it is:" + grid.items[0].selected);
// Note: A richgrid in seltype=single mode fires "select" events from selectItem
grid.toggleItemSelection(grid.items[0]);
@ -444,6 +447,39 @@ gTests.push({
}
});
gTests.push({
desc: "selectNone",
run: function() {
let grid = doc.querySelector("#grid-select2");
is(typeof grid.selectNone, "function", "selectNone is a function on the grid");
is(grid.itemCount, 2, "2 items initially");
// selectNone should fire a selectionchange event
let handler = {
handleEvent: function(aEvent) {}
};
let handlerStub = stubMethod(handler, "handleEvent");
doc.defaultView.addEventListener("selectionchange", handler, false);
info("selectionchange listener added");
grid.items[0].selected=true;
grid.items[1].selected=true;
is(grid.selectedItems.length, 2, "Both items are selected before calling selectNone");
grid.selectNone();
is(grid.selectedItems.length, 0, "Nothing selected when we selectNone");
ok(!(grid.items[0].selected || grid.items[1].selected), "selected properties all falsy when we selectNone");
is(handlerStub.callCount, 1, "selectionchange event handler was called when we selectNone");
is(handlerStub.calledWith[0].type, "selectionchange", "handler got a selectionchange event");
is(handlerStub.calledWith[0].target, grid, "selectionchange event had the originating grid as the target");
handlerStub.restore();
doc.defaultView.removeEventListener("selectionchange", handler, false);
}
});
function gridSlotsSetup() {
let grid = this.grid = doc.createElement("richgrid");
grid.setAttribute("minSlots", 6);

View File

@ -41,19 +41,28 @@ View.prototype = {
},
_adjustDOMforViewState: function _adjustDOMforViewState(aState) {
if (this._set) {
if (undefined == aState)
aState = this._set.getAttribute("viewstate");
this._set.setAttribute("suppressonselect", (aState == "snapped"));
if (aState == "portrait") {
this._set.setAttribute("vertical", true);
} else {
this._set.removeAttribute("vertical");
}
this._set.arrangeItems();
let grid = this._set;
if (!grid) {
return;
}
if (!aState) {
aState = grid.getAttribute("viewstate");
}
switch (aState) {
case "snapped":
grid.setAttribute("nocontext", true);
grid.selectNone();
break;
case "portrait":
grid.removeAttribute("nocontext");
grid.setAttribute("vertical", true);
break;
default:
grid.removeAttribute("nocontext");
grid.removeAttribute("vertical");
}
if ("arrangeItems" in grid) {
grid.arrangeItems();
}
},

View File

@ -207,11 +207,7 @@ menulist {
color: white;
}
.menu-popup > richlistbox[left-hand="true"] > richlistitem {
padding-left: 50px;
}
.menu-popup > richlistbox[left-hand="false"] > richlistitem {
.menu-popup > richlistbox > richlistitem {
padding-right: 50px;
}

View File

@ -27,28 +27,17 @@ this.SignInToWebsiteUX = {
init: function SignInToWebsiteUX_init() {
/*
* bug 793906 - temporarily disabling desktop UI so we can
* focus on b2g without worrying about desktop as well
*
Services.obs.addObserver(this, "identity-request", false);
Services.obs.addObserver(this, "identity-auth", false);
Services.obs.addObserver(this, "identity-auth-complete", false);
Services.obs.addObserver(this, "identity-login-state-changed", false);
*/
},
uninit: function SignInToWebsiteUX_uninit() {
/*
* As above:
* bug 793906 - temporarily disabling desktop UI so we can
* focus on b2g without worrying about desktop as well
*
Services.obs.removeObserver(this, "identity-request");
Services.obs.removeObserver(this, "identity-auth");
Services.obs.removeObserver(this, "identity-auth-complete");
Services.obs.removeObserver(this, "identity-login-state-changed");
*/
},
observe: function SignInToWebsiteUX_observe(aSubject, aTopic, aData) {

View File

@ -7,6 +7,3 @@ MOCHITEST_BROWSER_FILES += \
browser_taskbar_preview.js \
$(NULL)
endif
# bug 793906 - temporarily disabling desktop UI while working on b2g
# browser_SignInToWebsite.js

View File

@ -1,5 +1,6 @@
[DEFAULT]
[browser_NetworkPrioritizer.js]
[browser_SignInToWebsite.js]
[browser_UITour.js]
support-files = uitour.*

View File

@ -222,6 +222,7 @@ if test -n "$gonkdir" ; then
15)
GONK_INCLUDES="-I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/frameworks/base/include -I$gonkdir/frameworks/base/services/camera -I$gonkdir/frameworks/base/include/media/stagefright -I$gonkdir/frameworks/base/include/media/stagefright/openmax -I$gonkdir/frameworks/base/media/libstagefright/rtsp -I$gonkdir/frameworks/base/media/libstagefright/include -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib -I$gonkdir/dalvik/libnativehelper/include/nativehelper"
MOZ_B2G_BT=1
MOZ_B2G_BT_BLUEZ=1
MOZ_B2G_CAMERA=1
MOZ_OMX_DECODER=1
AC_SUBST(MOZ_OMX_DECODER)
@ -230,9 +231,15 @@ if test -n "$gonkdir" ; then
17|18)
GONK_INCLUDES="-I$gonkdir/frameworks/native/include -I$gonkdir/frameworks/av/include -I$gonkdir/frameworks/av/include/media -I$gonkdir/frameworks/av/include/camera -I$gonkdir/frameworks/native/include/media/openmax -I$gonkdir/frameworks/av/media/libstagefright/include"
if test -d "$gonkdir/external/bluetooth/bluez"; then
GONK_INCLUDES+=" -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib"
GONK_INCLUDES="$GONK_INCLUDES -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib"
MOZ_B2G_BT=1
MOZ_B2G_BT_BLUEZ=1
fi
if test -d "$gonkdir/external/bluetooth/bluedroid"; then
MOZ_B2G_BT=1
MOZ_B2G_BT_BLUEDROID=1
fi
MOZ_B2G_CAMERA=1
MOZ_OMX_DECODER=1
AC_SUBST(MOZ_OMX_DECODER)
@ -7301,6 +7308,8 @@ if test -n "$MOZ_B2G_BT"; then
AC_DEFINE(MOZ_B2G_BT)
fi
AC_SUBST(MOZ_B2G_BT)
AC_SUBST(MOZ_B2G_BT_BLUEZ)
AC_SUBST(MOZ_B2G_BT_BLUEDROID)
dnl ========================================================
dnl = Enable Pico Speech Synthesis (Gonk usually)

View File

@ -561,8 +561,7 @@ BluetoothHfpManager::HandleVoiceConnectionChanged()
NS_ENSURE_TRUE_VOID(connection);
nsCOMPtr<nsIDOMMozMobileConnectionInfo> voiceInfo;
// TODO: Bug 921991 - B2G BT: support multiple sim cards
connection->GetVoiceConnectionInfo(0, getter_AddRefs(voiceInfo));
connection->GetVoiceConnectionInfo(getter_AddRefs(voiceInfo));
NS_ENSURE_TRUE_VOID(voiceInfo);
nsString type;
@ -598,8 +597,7 @@ BluetoothHfpManager::HandleVoiceConnectionChanged()
* - manual: set mNetworkSelectionMode to 1 (manual)
*/
nsString mode;
// TODO: Bug 921991 - B2G BT: support multiple sim cards
connection->GetNetworkSelectionMode(0, mode);
connection->GetNetworkSelectionMode(mode);
if (mode.EqualsLiteral("manual")) {
mNetworkSelectionMode = 1;
} else {

View File

@ -292,9 +292,8 @@ BluetoothRilListener::StartMobileConnectionListening()
do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
NS_ENSURE_TRUE(provider, false);
// TODO: Bug 921991 - B2G BT: support multiple sim cards
nsresult rv = provider->
RegisterMobileConnectionMsg(0, mMobileConnectionListener);
RegisterMobileConnectionMsg(mMobileConnectionListener);
return NS_SUCCEEDED(rv);
}
@ -305,9 +304,8 @@ BluetoothRilListener::StopMobileConnectionListening()
do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
NS_ENSURE_TRUE(provider, false);
// TODO: Bug 921991 - B2G BT: support multiple sim cards
nsresult rv = provider->
UnregisterMobileConnectionMsg(0, mMobileConnectionListener);
UnregisterMobileConnectionMsg(mMobileConnectionListener);
return NS_SUCCEEDED(rv);
}

View File

@ -44,7 +44,11 @@
#if defined(MOZ_B2G_BT)
# if defined(MOZ_BLUETOOTH_GONK)
# include "BluetoothGonkService.h"
#ifdef MOZ_B2G_BT_BLUEZ
#include "BluetoothGonkService.h"
#else
#include "BluetoothServiceBluedroid.h"
#endif
# elif defined(MOZ_BLUETOOTH_DBUS)
# include "BluetoothDBusService.h"
# else
@ -304,9 +308,15 @@ BluetoothService::Create()
#endif
#if defined(MOZ_BLUETOOTH_GONK)
#ifdef MOZ_B2G_BT_BLUEDROID
return new BluetoothServiceBluedroid();
#else
return new BluetoothGonkService();
#endif
#elif defined(MOZ_BLUETOOTH_DBUS)
#ifdef MOZ_B2G_BT_BLUEZ
return new BluetoothDBusService();
#endif
#endif
BT_WARNING("No platform support for bluetooth!");
return nullptr;

View File

@ -0,0 +1,341 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*-
/* vim: set ts=2 et sw=2 tw=80: */
/*
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#include "BluetoothServiceBluedroid.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothUtils.h"
#include "BluetoothUuid.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/ipc/UnixSocket.h"
using namespace mozilla;
using namespace mozilla::ipc;
USING_BLUETOOTH_NAMESPACE
nsresult
BluetoothServiceBluedroid::StartInternal()
{
return NS_OK;
}
nsresult
BluetoothServiceBluedroid::StopInternal()
{
return NS_OK;
}
bool
BluetoothServiceBluedroid::IsEnabledInternal()
{
return true;
}
nsresult
BluetoothServiceBluedroid::GetDefaultAdapterPathInternal(
BluetoothReplyRunnable* aRunnable)
{
return NS_OK;
}
nsresult
BluetoothServiceBluedroid::GetConnectedDevicePropertiesInternal(
uint16_t aProfileId, BluetoothReplyRunnable* aRunnable)
{
return NS_OK;
}
nsresult
BluetoothServiceBluedroid::GetPairedDevicePropertiesInternal(
const nsTArray<nsString>& aDeviceAddress, BluetoothReplyRunnable* aRunnable)
{
return NS_OK;
}
nsresult
BluetoothServiceBluedroid::StartDiscoveryInternal(
BluetoothReplyRunnable* aRunnable)
{
return NS_OK;
}
nsresult
BluetoothServiceBluedroid::StopDiscoveryInternal(
BluetoothReplyRunnable* aRunnable)
{
return NS_OK;
}
nsresult
BluetoothServiceBluedroid::GetDevicePropertiesInternal(
const BluetoothSignal& aSignal)
{
return NS_OK;
}
nsresult
BluetoothServiceBluedroid::SetProperty(BluetoothObjectType aType,
const BluetoothNamedValue& aValue,
BluetoothReplyRunnable* aRunnable)
{
return NS_OK;
}
bool
BluetoothServiceBluedroid::GetDevicePath(const nsAString& aAdapterPath,
const nsAString& aDeviceAddress,
nsAString& aDevicePath)
{
return true;
}
bool
BluetoothServiceBluedroid::AddServiceRecords(const char* serviceName,
unsigned long long uuidMsb,
unsigned long long uuidLsb,
int channel)
{
return true;
}
bool
BluetoothServiceBluedroid::RemoveServiceRecords(const char* serviceName,
unsigned long long uuidMsb,
unsigned long long uuidLsb,
int channel)
{
return true;
}
bool
BluetoothServiceBluedroid::AddReservedServicesInternal(
const nsTArray<uint32_t>& aServices,
nsTArray<uint32_t>& aServiceHandlesContainer)
{
return true;
}
bool
BluetoothServiceBluedroid::RemoveReservedServicesInternal(
const nsTArray<uint32_t>& aServiceHandles)
{
return true;
}
nsresult
BluetoothServiceBluedroid::GetScoSocket(
const nsAString& aObjectPath, bool aAuth, bool aEncrypt,
mozilla::ipc::UnixSocketConsumer* aConsumer)
{
return NS_OK;
}
nsresult
BluetoothServiceBluedroid::GetServiceChannel(
const nsAString& aDeviceAddress,
const nsAString& aServiceUuid,
BluetoothProfileManagerBase* aManager)
{
return NS_OK;
}
bool
BluetoothServiceBluedroid::UpdateSdpRecords(
const nsAString& aDeviceAddress,
BluetoothProfileManagerBase* aManager)
{
return true;
}
nsresult
BluetoothServiceBluedroid::CreatePairedDeviceInternal(
const nsAString& aDeviceAddress, int aTimeout,
BluetoothReplyRunnable* aRunnable)
{
return NS_OK;
}
nsresult
BluetoothServiceBluedroid::RemoveDeviceInternal(
const nsAString& aDeviceObjectPath,
BluetoothReplyRunnable* aRunnable)
{
return NS_OK;
}
bool
BluetoothServiceBluedroid::SetPinCodeInternal(
const nsAString& aDeviceAddress, const nsAString& aPinCode,
BluetoothReplyRunnable* aRunnable)
{
return true;
}
bool
BluetoothServiceBluedroid::SetPasskeyInternal(
const nsAString& aDeviceAddress, uint32_t aPasskey,
BluetoothReplyRunnable* aRunnable)
{
return true;
}
bool
BluetoothServiceBluedroid::SetPairingConfirmationInternal(
const nsAString& aDeviceAddress, bool aConfirm,
BluetoothReplyRunnable* aRunnable)
{
return true;
}
bool
BluetoothServiceBluedroid::SetAuthorizationInternal(
const nsAString& aDeviceAddress, bool aAllow,
BluetoothReplyRunnable* aRunnable)
{
return true;
}
nsresult
BluetoothServiceBluedroid::PrepareAdapterInternal()
{
return NS_OK;
}
void
BluetoothServiceBluedroid::Connect(const nsAString& aDeviceAddress,
uint32_t aCod,
uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable)
{
}
bool
BluetoothServiceBluedroid::IsConnected(uint16_t aProfileId)
{
return true;
}
void
BluetoothServiceBluedroid::Disconnect(
const nsAString& aDeviceAddress, uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothServiceBluedroid::SendFile(const nsAString& aDeviceAddress,
BlobParent* aBlobParent,
BlobChild* aBlobChild,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothServiceBluedroid::StopSendingFile(const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothServiceBluedroid::ConfirmReceivingFile(
const nsAString& aDeviceAddress, bool aConfirm,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothServiceBluedroid::ConnectSco(BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothServiceBluedroid::DisconnectSco(BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothServiceBluedroid::IsScoConnected(BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothServiceBluedroid::SendMetaData(const nsAString& aTitle,
const nsAString& aArtist,
const nsAString& aAlbum,
int64_t aMediaNumber,
int64_t aTotalMediaCount,
int64_t aDuration,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothServiceBluedroid::SendPlayStatus(
int64_t aDuration, int64_t aPosition,
const nsAString& aPlayStatus,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothServiceBluedroid::UpdatePlayStatus(
uint32_t aDuration, uint32_t aPosition, ControlPlayStatus aPlayStatus)
{
}
nsresult
BluetoothServiceBluedroid::SendSinkMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage)
{
return NS_OK;
}
nsresult
BluetoothServiceBluedroid::SendInputMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage)
{
return NS_OK;
}
void
BluetoothServiceBluedroid::AnswerWaitingCall(BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothServiceBluedroid::IgnoreWaitingCall(BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothServiceBluedroid::ToggleCalls(BluetoothReplyRunnable* aRunnable)
{
}

View File

@ -0,0 +1,189 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*-
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_bluetooth_bluetoothservicebluedroid_h__
#define mozilla_dom_bluetooth_bluetoothservicebluedroid_h__
#include "BluetoothCommon.h"
#include "BluetoothService.h"
class DBusMessage;
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothServiceBluedroid : public BluetoothService
{
public:
virtual nsresult StartInternal();
virtual nsresult StopInternal();
virtual bool IsEnabledInternal();
virtual nsresult GetDefaultAdapterPathInternal(
BluetoothReplyRunnable* aRunnable);
virtual nsresult GetConnectedDevicePropertiesInternal(uint16_t aProfileId,
BluetoothReplyRunnable* aRunnable);
virtual nsresult GetPairedDevicePropertiesInternal(
const nsTArray<nsString>& aDeviceAddress,
BluetoothReplyRunnable* aRunnable);
virtual nsresult StartDiscoveryInternal(BluetoothReplyRunnable* aRunnable);
virtual nsresult StopDiscoveryInternal(BluetoothReplyRunnable* aRunnable);
virtual nsresult
GetDevicePropertiesInternal(const BluetoothSignal& aSignal);
virtual nsresult
SetProperty(BluetoothObjectType aType,
const BluetoothNamedValue& aValue,
BluetoothReplyRunnable* aRunnable);
virtual bool
GetDevicePath(const nsAString& aAdapterPath,
const nsAString& aDeviceAddress,
nsAString& aDevicePath);
static bool
AddServiceRecords(const char* serviceName,
unsigned long long uuidMsb,
unsigned long long uuidLsb,
int channel);
static bool
RemoveServiceRecords(const char* serviceName,
unsigned long long uuidMsb,
unsigned long long uuidLsb,
int channel);
static bool
AddReservedServicesInternal(const nsTArray<uint32_t>& aServices,
nsTArray<uint32_t>& aServiceHandlesContainer);
static bool
RemoveReservedServicesInternal(const nsTArray<uint32_t>& aServiceHandles);
virtual nsresult
GetScoSocket(const nsAString& aObjectPath,
bool aAuth,
bool aEncrypt,
mozilla::ipc::UnixSocketConsumer* aConsumer);
virtual nsresult
GetServiceChannel(const nsAString& aDeviceAddress,
const nsAString& aServiceUuid,
BluetoothProfileManagerBase* aManager);
virtual bool
UpdateSdpRecords(const nsAString& aDeviceAddress,
BluetoothProfileManagerBase* aManager);
virtual nsresult
CreatePairedDeviceInternal(const nsAString& aDeviceAddress,
int aTimeout,
BluetoothReplyRunnable* aRunnable);
virtual nsresult
RemoveDeviceInternal(const nsAString& aDeviceObjectPath,
BluetoothReplyRunnable* aRunnable);
virtual bool
SetPinCodeInternal(const nsAString& aDeviceAddress, const nsAString& aPinCode,
BluetoothReplyRunnable* aRunnable);
virtual bool
SetPasskeyInternal(const nsAString& aDeviceAddress, uint32_t aPasskey,
BluetoothReplyRunnable* aRunnable);
virtual bool
SetPairingConfirmationInternal(const nsAString& aDeviceAddress, bool aConfirm,
BluetoothReplyRunnable* aRunnable);
virtual bool
SetAuthorizationInternal(const nsAString& aDeviceAddress, bool aAllow,
BluetoothReplyRunnable* aRunnable);
virtual nsresult
PrepareAdapterInternal();
virtual void
Connect(const nsAString& aDeviceAddress,
uint32_t aCod,
uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable);
virtual bool
IsConnected(uint16_t aProfileId);
virtual void
Disconnect(const nsAString& aDeviceAddress, uint16_t aServiceUuid,
BluetoothReplyRunnable* aRunnable);
virtual void
SendFile(const nsAString& aDeviceAddress,
BlobParent* aBlobParent,
BlobChild* aBlobChild,
BluetoothReplyRunnable* aRunnable);
virtual void
StopSendingFile(const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable);
virtual void
ConfirmReceivingFile(const nsAString& aDeviceAddress, bool aConfirm,
BluetoothReplyRunnable* aRunnable);
virtual void
ConnectSco(BluetoothReplyRunnable* aRunnable);
virtual void
DisconnectSco(BluetoothReplyRunnable* aRunnable);
virtual void
IsScoConnected(BluetoothReplyRunnable* aRunnable);
virtual void
AnswerWaitingCall(BluetoothReplyRunnable* aRunnable);
virtual void
IgnoreWaitingCall(BluetoothReplyRunnable* aRunnable);
virtual void
ToggleCalls(BluetoothReplyRunnable* aRunnable);
virtual void
SendMetaData(const nsAString& aTitle,
const nsAString& aArtist,
const nsAString& aAlbum,
int64_t aMediaNumber,
int64_t aTotalMediaCount,
int64_t aDuration,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual void
SendPlayStatus(int64_t aDuration,
int64_t aPosition,
const nsAString& aPlayStatus,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual void
UpdatePlayStatus(uint32_t aDuration,
uint32_t aPosition,
ControlPlayStatus aPlayStatus) MOZ_OVERRIDE;
virtual nsresult
SendSinkMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage) MOZ_OVERRIDE;
virtual nsresult
SendInputMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage) MOZ_OVERRIDE;
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -27,11 +27,12 @@
#include <errno.h>
#include <sys/socket.h>
#ifdef MOZ_B2G_BT_BLUEZ
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/sco.h>
#endif
#include "BluetoothUnixSocketConnector.h"
#include "nsThreadUtils.h"
@ -43,6 +44,7 @@ static const int L2CAP_SO_SNDBUF = 400 * 1024; // 400 KB send buffer
static const int L2CAP_SO_RCVBUF = 400 * 1024; // 400 KB receive buffer
static const int L2CAP_MAX_MTU = 65000;
#ifdef MOZ_B2G_BT_BLUEZ
static
int get_bdaddr(const char *str, bdaddr_t *ba)
{
@ -62,6 +64,8 @@ void get_bdaddr_as_string(const bdaddr_t *ba, char *str) {
b[5], b[4], b[3], b[2], b[1], b[0]);
}
#endif
BluetoothUnixSocketConnector::BluetoothUnixSocketConnector(
BluetoothSocketType aType,
int aChannel,
@ -76,6 +80,7 @@ BluetoothUnixSocketConnector::BluetoothUnixSocketConnector(
bool
BluetoothUnixSocketConnector::SetUp(int aFd)
{
#ifdef MOZ_B2G_BT_BLUEZ
int lm = 0;
int sndbuf, rcvbuf;
@ -157,7 +162,7 @@ BluetoothUnixSocketConnector::SetUp(int aFd)
}
}
}
#endif
return true;
}
@ -167,6 +172,7 @@ BluetoothUnixSocketConnector::Create()
MOZ_ASSERT(!NS_IsMainThread());
int fd = -1;
#ifdef MOZ_B2G_BT_BLUEZ
switch (mType) {
case BluetoothSocketType::RFCOMM:
fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
@ -193,7 +199,7 @@ BluetoothUnixSocketConnector::Create()
BT_WARNING("Could not set up socket!");
return -1;
}
#endif
return fd;
}
@ -203,6 +209,7 @@ BluetoothUnixSocketConnector::CreateAddr(bool aIsServer,
sockaddr_any& aAddr,
const char* aAddress)
{
#ifdef MOZ_B2G_BT_BLUEZ
// Set to BDADDR_ANY, if it's not a server, we'll reset.
bdaddr_t bd_address_obj = {{0, 0, 0, 0, 0, 0}};
@ -242,6 +249,7 @@ BluetoothUnixSocketConnector::CreateAddr(bool aIsServer,
BT_WARNING("Socket type unknown!");
return false;
}
#endif
return true;
}
@ -249,6 +257,7 @@ void
BluetoothUnixSocketConnector::GetSocketAddr(const sockaddr_any& aAddr,
nsAString& aAddrStr)
{
#ifdef MOZ_B2G_BT_BLUEZ
char addr[18];
switch (mType) {
case BluetoothSocketType::RFCOMM:
@ -265,4 +274,5 @@ BluetoothUnixSocketConnector::GetSocketAddr(const sockaddr_any& aAddr,
MOZ_CRASH("Socket should be either RFCOMM or SCO!");
}
aAddrStr.AssignASCII(addr);
#endif
}

View File

@ -36,6 +36,14 @@ DEFINES += -DMOZ_BLUETOOTH_DBUS
endif
endif
ifdef MOZ_B2G_BT_BLUEZ
DEFINES += -DMOZ_B2G_BT_BLUEZ
endif
ifdef MOZ_B2G_BT_BLUEDROID
DEFINES += -DMOZ_B2G_BT_BLUEDROID
endif
# Add VPATH to LOCAL_INCLUDES so we are going to include the correct backend
# subdirectory.
LOCAL_INCLUDES += $(VPATH:%=-I%)

View File

@ -24,6 +24,9 @@ BEGIN_BLUETOOTH_NAMESPACE
class BluetoothDBusService : public BluetoothService
{
public:
BluetoothDBusService();
~BluetoothDBusService();
bool IsReady();
virtual nsresult StartInternal() MOZ_OVERRIDE;
@ -168,11 +171,6 @@ public:
virtual nsresult
SendInputMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage) MOZ_OVERRIDE;
protected:
BluetoothDBusService();
~BluetoothDBusService();
private:
/**
* For DBus Control method of "UpdateNotification", event id should be

View File

@ -53,14 +53,19 @@ if CONFIG['MOZ_B2G_BT']:
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
CPP_SOURCES += [
'linux/BluetoothDBusService.cpp',
'gonk/BluetoothGonkService.cpp',
]
if CONFIG['MOZ_B2G_BT_BLUEZ']:
CPP_SOURCES += [
'linux/BluetoothDBusService.cpp',
'gonk/BluetoothGonkService.cpp',
]
if CONFIG['MOZ_B2G_BT_BLUEDROID']:
CPP_SOURCES += [
'BluetoothServiceBluedroid.cpp',
]
else:
if CONFIG['MOZ_ENABLE_DBUS']:
CPP_SOURCES += [
'linux/BluetoothDBusService.cpp',
'linux/BluetoothDBusService.cpp',
]
EXPORTS.mozilla.dom.bluetooth.ipc += [

View File

@ -33,7 +33,7 @@ interface nsIMobileConnectionListener : nsISupports
* XPCOM component (in the content process) that provides the mobile
* network information.
*/
[scriptable, uuid(84278a49-0f05-4585-b3f4-c74882ae5719)]
[scriptable, uuid(c66652e0-0628-11e3-8ffd-0800200c9a66)]
interface nsIMobileConnectionProvider : nsISupports
{
/**
@ -41,71 +41,47 @@ interface nsIMobileConnectionProvider : nsISupports
* RadioInterfaceLayer in the chrome process. Only a content process that has
* the 'mobileconnection' permission is allowed to register.
*/
void registerMobileConnectionMsg(in unsigned long clientId,
in nsIMobileConnectionListener listener);
void unregisterMobileConnectionMsg(in unsigned long clientId,
in nsIMobileConnectionListener listener);
void registerMobileConnectionMsg(in nsIMobileConnectionListener listener);
void unregisterMobileConnectionMsg(in nsIMobileConnectionListener listener);
nsIDOMMozMobileConnectionInfo getVoiceConnectionInfo(in unsigned long clientId);
nsIDOMMozMobileConnectionInfo getDataConnectionInfo(in unsigned long clientId);
DOMString getIccId(in unsigned long clientId);
DOMString getNetworkSelectionMode(in unsigned long clientId);
readonly attribute nsIDOMMozMobileConnectionInfo voiceConnectionInfo;
readonly attribute nsIDOMMozMobileConnectionInfo dataConnectionInfo;
readonly attribute DOMString networkSelectionMode;
nsIDOMDOMRequest getNetworks(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest selectNetwork(in unsigned long clientId,
in nsIDOMWindow window,
in nsIDOMMozMobileNetworkInfo network);
nsIDOMDOMRequest selectNetworkAutomatically(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest getNetworks(in nsIDOMWindow window);
nsIDOMDOMRequest selectNetwork(in nsIDOMWindow window, in nsIDOMMozMobileNetworkInfo network);
nsIDOMDOMRequest selectNetworkAutomatically(in nsIDOMWindow window);
nsIDOMDOMRequest setRoamingPreference(in unsigned long clientId,
in nsIDOMWindow window,
nsIDOMDOMRequest setRoamingPreference(in nsIDOMWindow window,
in DOMString mode);
nsIDOMDOMRequest getRoamingPreference(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest getRoamingPreference(in nsIDOMWindow window);
nsIDOMDOMRequest setVoicePrivacyMode(in unsigned long clientId,
in nsIDOMWindow window,
nsIDOMDOMRequest setVoicePrivacyMode(in nsIDOMWindow window,
in bool enabled);
nsIDOMDOMRequest getVoicePrivacyMode(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest getVoicePrivacyMode(in nsIDOMWindow window);
nsIDOMDOMRequest sendMMI(in unsigned long clientId,
in nsIDOMWindow window,
in DOMString mmi);
nsIDOMDOMRequest cancelMMI(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest sendMMI(in nsIDOMWindow window, in DOMString mmi);
nsIDOMDOMRequest cancelMMI(in nsIDOMWindow window);
nsIDOMDOMRequest getCallForwardingOption(in unsigned long clientId,
in nsIDOMWindow window,
nsIDOMDOMRequest getCallForwardingOption(in nsIDOMWindow window,
in unsigned short reason);
nsIDOMDOMRequest setCallForwardingOption(in unsigned long clientId,
in nsIDOMWindow window,
nsIDOMDOMRequest setCallForwardingOption(in nsIDOMWindow window,
in nsIDOMMozMobileCFInfo CFInfo);
nsIDOMDOMRequest getCallBarringOption(in unsigned long clientId,
in nsIDOMWindow window,
in jsval option);
nsIDOMDOMRequest setCallBarringOption(in unsigned long clientId,
in nsIDOMWindow window,
in jsval option);
nsIDOMDOMRequest changeCallBarringPassword(in unsigned long clientId,
in nsIDOMWindow window,
nsIDOMDOMRequest getCallBarringOption(in nsIDOMWindow window,
in jsval option);
nsIDOMDOMRequest setCallBarringOption(in nsIDOMWindow window,
in jsval option);
nsIDOMDOMRequest changeCallBarringPassword(in nsIDOMWindow window,
in jsval info);
nsIDOMDOMRequest setCallWaitingOption(in unsigned long clientId,
in nsIDOMWindow window,
nsIDOMDOMRequest setCallWaitingOption(in nsIDOMWindow window,
in bool enabled);
nsIDOMDOMRequest getCallWaitingOption(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest getCallWaitingOption(in nsIDOMWindow window);
nsIDOMDOMRequest setCallingLineIdRestriction(in unsigned long clientId,
in nsIDOMWindow window,
nsIDOMDOMRequest setCallingLineIdRestriction(in nsIDOMWindow window,
in unsigned short clirMode);
nsIDOMDOMRequest getCallingLineIdRestriction(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest getCallingLineIdRestriction(in nsIDOMWindow window);
nsIDOMDOMRequest exitEmergencyCbMode(in unsigned long clientId,
in nsIDOMWindow window);
nsIDOMDOMRequest exitEmergencyCbMode(in nsIDOMWindow window);
};

View File

@ -83,9 +83,6 @@ MobileConnection::MobileConnection()
mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
mWindow = nullptr;
// TODO: Bug 814629 - WebMobileConnection API: support multiple sim cards
mClientId = 0;
// Not being able to acquire the provider isn't fatal since we check
// for it explicitly below.
if (!mProvider) {
@ -104,7 +101,7 @@ MobileConnection::Init(nsPIDOMWindow* aWindow)
if (!CheckPermission("mobilenetwork") &&
CheckPermission("mobileconnection")) {
DebugOnly<nsresult> rv = mProvider->RegisterMobileConnectionMsg(mClientId, mListener);
DebugOnly<nsresult> rv = mProvider->RegisterMobileConnectionMsg(mListener);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"Failed registering mobile connection messages with provider");
@ -117,7 +114,7 @@ MobileConnection::Shutdown()
{
if (mProvider && mListener) {
mListener->Disconnect();
mProvider->UnregisterMobileConnectionMsg(mClientId, mListener);
mProvider->UnregisterMobileConnectionMsg(mListener);
mProvider = nullptr;
mListener = nullptr;
}
@ -176,7 +173,7 @@ MobileConnection::GetVoice(nsIDOMMozMobileConnectionInfo** voice)
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetVoiceConnectionInfo(mClientId, voice);
return mProvider->GetVoiceConnectionInfo(voice);
}
NS_IMETHODIMP
@ -187,7 +184,7 @@ MobileConnection::GetData(nsIDOMMozMobileConnectionInfo** data)
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetDataConnectionInfo(mClientId, data);
return mProvider->GetDataConnectionInfo(data);
}
NS_IMETHODIMP
@ -198,7 +195,7 @@ MobileConnection::GetNetworkSelectionMode(nsAString& networkSelectionMode)
if (!mProvider || !CheckPermission("mobileconnection")) {
return NS_OK;
}
return mProvider->GetNetworkSelectionMode(mClientId, networkSelectionMode);
return mProvider->GetNetworkSelectionMode(networkSelectionMode);
}
NS_IMETHODIMP
@ -214,7 +211,7 @@ MobileConnection::GetNetworks(nsIDOMDOMRequest** request)
return NS_ERROR_FAILURE;
}
return mProvider->GetNetworks(mClientId, GetOwner(), request);
return mProvider->GetNetworks(GetOwner(), request);
}
NS_IMETHODIMP
@ -230,7 +227,7 @@ MobileConnection::SelectNetwork(nsIDOMMozMobileNetworkInfo* network, nsIDOMDOMRe
return NS_ERROR_FAILURE;
}
return mProvider->SelectNetwork(mClientId, GetOwner(), network, request);
return mProvider->SelectNetwork(GetOwner(), network, request);
}
NS_IMETHODIMP
@ -246,7 +243,7 @@ MobileConnection::SelectNetworkAutomatically(nsIDOMDOMRequest** request)
return NS_ERROR_FAILURE;
}
return mProvider->SelectNetworkAutomatically(mClientId, GetOwner(), request);
return mProvider->SelectNetworkAutomatically(GetOwner(), request);
}
NS_IMETHODIMP
@ -262,7 +259,7 @@ MobileConnection::SetRoamingPreference(const nsAString& aMode, nsIDOMDOMRequest*
return NS_ERROR_FAILURE;
}
return mProvider->SetRoamingPreference(mClientId, GetOwner(), aMode, aDomRequest);
return mProvider->SetRoamingPreference(GetOwner(), aMode, aDomRequest);
}
NS_IMETHODIMP
@ -278,7 +275,7 @@ MobileConnection::GetRoamingPreference(nsIDOMDOMRequest** aDomRequest)
return NS_ERROR_FAILURE;
}
return mProvider->GetRoamingPreference(mClientId, GetOwner(), aDomRequest);
return mProvider->GetRoamingPreference(GetOwner(), aDomRequest);
}
NS_IMETHODIMP
@ -294,7 +291,7 @@ MobileConnection::SetVoicePrivacyMode(bool aEnabled, nsIDOMDOMRequest** aDomRequ
return NS_ERROR_FAILURE;
}
return mProvider->SetVoicePrivacyMode(mClientId, GetOwner(), aEnabled, aDomRequest);
return mProvider->SetVoicePrivacyMode(GetOwner(), aEnabled, aDomRequest);
}
NS_IMETHODIMP
@ -310,7 +307,7 @@ MobileConnection::GetVoicePrivacyMode(nsIDOMDOMRequest** aDomRequest)
return NS_ERROR_FAILURE;
}
return mProvider->GetVoicePrivacyMode(mClientId, GetOwner(), aDomRequest);
return mProvider->GetVoicePrivacyMode(GetOwner(), aDomRequest);
}
NS_IMETHODIMP
@ -325,7 +322,7 @@ MobileConnection::SendMMI(const nsAString& aMMIString,
return NS_ERROR_FAILURE;
}
return mProvider->SendMMI(mClientId, GetOwner(), aMMIString, aRequest);
return mProvider->SendMMI(GetOwner(), aMMIString, aRequest);
}
NS_IMETHODIMP
@ -339,7 +336,7 @@ MobileConnection::CancelMMI(nsIDOMDOMRequest** aRequest)
return NS_ERROR_FAILURE;
}
return mProvider->CancelMMI(mClientId, GetOwner(),aRequest);
return mProvider->CancelMMI(GetOwner(), aRequest);
}
NS_IMETHODIMP
@ -356,7 +353,7 @@ MobileConnection::GetCallForwardingOption(uint16_t aReason,
return NS_ERROR_FAILURE;
}
return mProvider->GetCallForwardingOption(mClientId, GetOwner(), aReason, aRequest);
return mProvider->GetCallForwardingOption(GetOwner(), aReason, aRequest);
}
NS_IMETHODIMP
@ -373,7 +370,7 @@ MobileConnection::SetCallForwardingOption(nsIDOMMozMobileCFInfo* aCFInfo,
return NS_ERROR_FAILURE;
}
return mProvider->SetCallForwardingOption(mClientId, GetOwner(), aCFInfo, aRequest);
return mProvider->SetCallForwardingOption(GetOwner(), aCFInfo, aRequest);
}
NS_IMETHODIMP
@ -390,7 +387,7 @@ MobileConnection::GetCallBarringOption(const JS::Value& aOption,
return NS_ERROR_FAILURE;
}
return mProvider->GetCallBarringOption(mClientId, GetOwner(), aOption, aRequest);
return mProvider->GetCallBarringOption(GetOwner(), aOption, aRequest);
}
NS_IMETHODIMP
@ -407,7 +404,7 @@ MobileConnection::SetCallBarringOption(const JS::Value& aOption,
return NS_ERROR_FAILURE;
}
return mProvider->SetCallBarringOption(mClientId, GetOwner(), aOption, aRequest);
return mProvider->SetCallBarringOption(GetOwner(), aOption, aRequest);
}
NS_IMETHODIMP
@ -424,7 +421,7 @@ MobileConnection::ChangeCallBarringPassword(const JS::Value& aInfo,
return NS_ERROR_FAILURE;
}
return mProvider->ChangeCallBarringPassword(mClientId, GetOwner(), aInfo, aRequest);
return mProvider->ChangeCallBarringPassword(GetOwner(), aInfo, aRequest);
}
NS_IMETHODIMP
@ -440,7 +437,7 @@ MobileConnection::GetCallWaitingOption(nsIDOMDOMRequest** aRequest)
return NS_ERROR_FAILURE;
}
return mProvider->GetCallWaitingOption(mClientId, GetOwner(), aRequest);
return mProvider->GetCallWaitingOption(GetOwner(), aRequest);
}
NS_IMETHODIMP
@ -457,7 +454,7 @@ MobileConnection::SetCallWaitingOption(bool aEnabled,
return NS_ERROR_FAILURE;
}
return mProvider->SetCallWaitingOption(mClientId, GetOwner(), aEnabled, aRequest);
return mProvider->SetCallWaitingOption(GetOwner(), aEnabled, aRequest);
}
NS_IMETHODIMP
@ -473,7 +470,7 @@ MobileConnection::GetCallingLineIdRestriction(nsIDOMDOMRequest** aRequest)
return NS_ERROR_FAILURE;
}
return mProvider->GetCallingLineIdRestriction(mClientId, GetOwner(), aRequest);
return mProvider->GetCallingLineIdRestriction(GetOwner(), aRequest);
}
NS_IMETHODIMP
@ -490,7 +487,7 @@ MobileConnection::SetCallingLineIdRestriction(unsigned short aClirMode,
return NS_ERROR_FAILURE;
}
return mProvider->SetCallingLineIdRestriction(mClientId, GetOwner(), aClirMode, aRequest);
return mProvider->SetCallingLineIdRestriction(GetOwner(), aClirMode, aRequest);
}
NS_IMETHODIMP
@ -506,7 +503,7 @@ MobileConnection::ExitEmergencyCbMode(nsIDOMDOMRequest** aRequest)
return NS_ERROR_FAILURE;
}
return mProvider->ExitEmergencyCbMode(mClientId, GetOwner(), aRequest);
return mProvider->ExitEmergencyCbMode(GetOwner(), aRequest);
}
// nsIMobileConnectionListener

View File

@ -48,8 +48,6 @@ private:
nsRefPtr<Listener> mListener;
nsWeakPtr mWindow;
uint32_t mClientId;
bool CheckPermission(const char* type);
};

View File

@ -44,8 +44,7 @@ this.PhoneNumberUtils = {
#ifdef MOZ_B2G_RIL
// Get network mcc
// TODO: Bug 926740 - PhoneNumberUtils for multisim
let voice = mobileConnection.getVoiceConnectionInfo(0);
let voice = mobileConnection.voiceConnectionInfo;
if (voice && voice.network && voice.network.mcc) {
mcc = voice.network.mcc;
}

View File

@ -88,13 +88,13 @@ const RIL_IPC_MSG_NAMES = [
"RIL:StkCommand",
"RIL:StkSessionEnd",
"RIL:DataError",
"RIL:SetCallForwardingOptions",
"RIL:GetCallForwardingOptions",
"RIL:SetCallBarringOptions",
"RIL:GetCallBarringOptions",
"RIL:SetCallForwardingOption",
"RIL:GetCallForwardingOption",
"RIL:SetCallBarringOption",
"RIL:GetCallBarringOption",
"RIL:ChangeCallBarringPassword",
"RIL:SetCallWaitingOptions",
"RIL:GetCallWaitingOptions",
"RIL:SetCallWaitingOption",
"RIL:GetCallWaitingOption",
"RIL:SetCallingLineIdRestriction",
"RIL:GetCallingLineIdRestriction",
"RIL:CellBroadcastReceived",
@ -384,13 +384,13 @@ CellBroadcastEtwsInfo.prototype = {
popup: null
};
function CallBarringOptions(options) {
this.program = options.program;
this.enabled = options.enabled;
this.password = options.password;
this.serviceClass = options.serviceClass;
function CallBarringOption(option) {
this.program = option.program;
this.enabled = option.enabled;
this.password = option.password;
this.serviceClass = option.serviceClass;
}
CallBarringOptions.prototype = {
CallBarringOption.prototype = {
__exposedProps__ : {program: 'r',
enabled: 'r',
password: 'r',
@ -449,30 +449,17 @@ IccCardLockError.prototype = {
};
function RILContentHelper() {
this.numClients = gNumRadioInterfaces;
debug("Number of clients: " + this.numClients);
this.rilContexts = [];
for (let clientId = 0; clientId < this.numClients; clientId++) {
this.rilContexts[clientId] = {
cardState: RIL.GECKO_CARDSTATE_UNKNOWN,
networkSelectionMode: RIL.GECKO_NETWORK_SELECTION_UNKNOWN,
iccInfo: null,
voiceConnectionInfo: new MobileConnectionInfo(),
dataConnectionInfo: new MobileConnectionInfo()
};
}
this.rilContext = {
cardState: RIL.GECKO_CARDSTATE_UNKNOWN,
networkSelectionMode: RIL.GECKO_NETWORK_SELECTION_UNKNOWN,
iccInfo: null,
voiceConnectionInfo: new MobileConnectionInfo(),
dataConnectionInfo: new MobileConnectionInfo()
};
this.voicemailInfo = new VoicemailInfo();
this.initDOMRequestHelper(/* aWindow */ null, RIL_IPC_MSG_NAMES);
this._windowsMap = [];
this._selectingNetworks = [];
this._mobileConnectionListeners = [];
this._cellBroadcastListeners = [];
this._voicemailListeners = [];
this._iccListeners = [];
Services.obs.addObserver(this, "xpcom-shutdown", false);
}
@ -538,103 +525,88 @@ RILContentHelper.prototype = {
* 1. Should clear iccInfo to null if there is no card detected.
* 2. Need to create corresponding object based on iccType.
*/
updateIccInfo: function updateIccInfo(clientId, newInfo) {
let rilContext = this.rilContexts[clientId];
updateIccInfo: function updateIccInfo(newInfo) {
// Card is not detected, clear iccInfo to null.
if (!newInfo || !newInfo.iccType) {
rilContext.iccInfo = null;
this.rilContext.iccInfo = null;
return;
}
// If iccInfo is null, new corresponding object based on iccType.
if (!rilContext.iccInfo) {
if (!this.rilContext.iccInfo) {
if (newInfo.iccType === "ruim" || newInfo.iccType === "csim") {
rilContext.iccInfo = new CdmaIccInfo();
this.rilContext.iccInfo = new CdmaIccInfo();
} else {
rilContext.iccInfo = new GsmIccInfo();
this.rilContext.iccInfo = new GsmIccInfo();
}
}
this.updateInfo(newInfo, rilContext.iccInfo);
this.updateInfo(newInfo, this.rilContext.iccInfo);
},
_windowsMap: null,
rilContexts: null,
rilContext: null,
getRilContext: function getRilContext(clientId) {
// Update ril contexts by sending IPC message to chrome only when the first
getRilContext: function getRilContext() {
// Update ril context by sending IPC message to chrome only when the first
// time we require it. The information will be updated by following info
// changed messages.
this.getRilContext = function getRilContext(clientId) {
return this.rilContexts[clientId];
this.getRilContext = function getRilContext() {
return this.rilContext;
};
for (let cId = 0; cId < this.numClients; cId++) {
let rilContext =
cpmm.sendSyncMessage("RIL:GetRilContext", {clientId: cId})[0];
if (!rilContext) {
debug("Received null rilContext from chrome process.");
continue;
}
this.rilContexts[cId].cardState = rilContext.cardState;
this.rilContexts[cId].networkSelectionMode = rilContext.networkSelectionMode;
this.updateIccInfo(cId, rilContext.iccInfo);
this.updateConnectionInfo(rilContext.voice, this.rilContexts[cId].voiceConnectionInfo);
this.updateConnectionInfo(rilContext.data, this.rilContexts[cId].dataConnectionInfo);
let rilContext =
cpmm.sendSyncMessage("RIL:GetRilContext", {clientId: 0})[0];
if (!rilContext) {
debug("Received null rilContext from chrome process.");
return;
}
this.rilContext.cardState = rilContext.cardState;
this.rilContext.networkSelectionMode = rilContext.networkSelectionMode;
this.updateIccInfo(rilContext.iccInfo);
this.updateConnectionInfo(rilContext.voice, this.rilContext.voiceConnectionInfo);
this.updateConnectionInfo(rilContext.data, this.rilContext.dataConnectionInfo);
return this.rilContexts[clientId];
},
/**
* nsIIccProvider
*/
get iccInfo() {
//TODO: Bug 814637 - WebIccManager API: support multiple sim cards.
let context = this.getRilContext(0);
return context && context.iccInfo;
},
get cardState() {
//TODO: Bug 814637 - WebIccManager API: support multiple sim cards.
let context = this.getRilContext(0);
return context && context.cardState;
return this.rilContext;
},
/**
* nsIMobileConnectionProvider
*/
getVoiceConnectionInfo: function getVoiceConnectionInfo(clientId) {
let context = this.getRilContext(clientId);
get iccInfo() {
let context = this.getRilContext();
return context && context.iccInfo;
},
get voiceConnectionInfo() {
let context = this.getRilContext();
return context && context.voiceConnectionInfo;
},
getDataConnectionInfo: function getDataConnectionInfo(clientId) {
let context = this.getRilContext(clientId);
get dataConnectionInfo() {
let context = this.getRilContext();
return context && context.dataConnectionInfo;
},
getIccId: function getIccId(clientId) {
let context = this.getRilContext(clientId);
return context && context.iccInfo.iccid;
get cardState() {
let context = this.getRilContext();
return context && context.cardState;
},
getNetworkSelectionMode: function getNetworkSelectionMode(clientId) {
let context = this.getRilContext(clientId);
get networkSelectionMode() {
let context = this.getRilContext();
return context && context.networkSelectionMode;
},
/**
* The networks that are currently trying to be selected (or "automatic").
* This helps ensure that only one network per client is selected at a time.
* The network that is currently trying to be selected (or "automatic").
* This helps ensure that only one network is selected at a time.
*/
_selectingNetworks: null,
_selectingNetwork: null,
getNetworks: function getNetworks(clientId, window) {
getNetworks: function getNetworks(window) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -644,7 +616,7 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:GetAvailableNetworks", {
clientId: clientId,
clientId: 0,
data: {
requestId: requestId
}
@ -652,14 +624,14 @@ RILContentHelper.prototype = {
return request;
},
selectNetwork: function selectNetwork(clientId, window, network) {
selectNetwork: function selectNetwork(window, network) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
if (this._selectingNetworks[clientId]) {
throw new Error("Already selecting a network: " + this._selectingNetworks[clientId]);
if (this._selectingNetwork) {
throw new Error("Already selecting a network: " + this._selectingNetwork);
}
if (!network) {
@ -677,8 +649,8 @@ RILContentHelper.prototype = {
let request = Services.DOMRequest.createRequest(window);
let requestId = this.getRequestId(request);
if (this.rilContexts[clientId].networkSelectionMode == RIL.GECKO_NETWORK_SELECTION_MANUAL &&
this.rilContexts[clientId].voiceConnectionInfo.network === network) {
if (this.rilContext.networkSelectionMode == RIL.GECKO_NETWORK_SELECTION_MANUAL &&
this.rilContext.voiceConnectionInfo.network === network) {
// Already manually selected this network, so schedule
// onsuccess to be fired on the next tick
@ -686,10 +658,10 @@ RILContentHelper.prototype = {
return request;
}
this._selectingNetworks[clientId] = network;
this._selectingNetwork = network;
cpmm.sendAsyncMessage("RIL:SelectNetwork", {
clientId: clientId,
clientId: 0,
data: {
requestId: requestId,
mnc: network.mnc,
@ -700,30 +672,30 @@ RILContentHelper.prototype = {
return request;
},
selectNetworkAutomatically: function selectNetworkAutomatically(clientId, window) {
selectNetworkAutomatically: function selectNetworkAutomatically(window) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
}
if (this._selectingNetworks[clientId]) {
throw new Error("Already selecting a network: " + this._selectingNetworks[clientId]);
if (this._selectingNetwork) {
throw new Error("Already selecting a network: " + this._selectingNetwork);
}
let request = Services.DOMRequest.createRequest(window);
let requestId = this.getRequestId(request);
if (this.rilContexts[clientId].networkSelectionMode == RIL.GECKO_NETWORK_SELECTION_AUTOMATIC) {
if (this.rilContext.networkSelectionMode == RIL.GECKO_NETWORK_SELECTION_AUTOMATIC) {
// Already using automatic selection mode, so schedule
// onsuccess to be be fired on the next tick
this.dispatchFireRequestSuccess(requestId, null);
return request;
}
this._selectingNetworks[clientId] = "automatic";
this._selectingNetwork = "automatic";
cpmm.sendAsyncMessage("RIL:SelectNetworkAuto", {
clientId: clientId,
clientId: 0,
data: {
requestId: requestId
}
@ -731,7 +703,7 @@ RILContentHelper.prototype = {
return request;
},
setRoamingPreference: function setRoamingPreference(clientId, window, mode) {
setRoamingPreference: function setRoamingPreference(window, mode) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -747,7 +719,7 @@ RILContentHelper.prototype = {
}
cpmm.sendAsyncMessage("RIL:SetRoamingPreference", {
clientId: clientId,
clientId: 0,
data: {
requestId: requestId,
mode: mode
@ -756,7 +728,7 @@ RILContentHelper.prototype = {
return request;
},
getRoamingPreference: function getRoamingPreference(clientId, window) {
getRoamingPreference: function getRoamingPreference(window) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -766,7 +738,7 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:GetRoamingPreference", {
clientId: clientId,
clientId: 0,
data: {
requestId: requestId
}
@ -774,7 +746,7 @@ RILContentHelper.prototype = {
return request;
},
setVoicePrivacyMode: function setVoicePrivacyMode(clientId, window, enabled) {
setVoicePrivacyMode: function setVoicePrivacyMode(window, enabled) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -784,7 +756,7 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:SetVoicePrivacyMode", {
clientId: clientId,
clientId: 0,
data: {
requestId: requestId,
enabled: enabled
@ -793,7 +765,7 @@ RILContentHelper.prototype = {
return request;
},
getVoicePrivacyMode: function getVoicePrivacyMode(clientId, window) {
getVoicePrivacyMode: function getVoicePrivacyMode(window) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -803,7 +775,7 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:GetVoicePrivacyMode", {
clientId: clientId,
clientId: 0,
data: {
requestId: requestId
}
@ -879,7 +851,7 @@ RILContentHelper.prototype = {
return request;
},
sendMMI: function sendMMI(clientId, window, mmi) {
sendMMI: function sendMMI(window, mmi) {
debug("Sending MMI " + mmi);
if (!window) {
throw Components.Exception("Can't get window object",
@ -892,7 +864,7 @@ RILContentHelper.prototype = {
this._windowsMap[requestId] = window;
cpmm.sendAsyncMessage("RIL:SendMMI", {
clientId: clientId,
clientId: 0,
data: {
mmi: mmi,
requestId: requestId
@ -901,7 +873,7 @@ RILContentHelper.prototype = {
return request;
},
cancelMMI: function cancelMMI(clientId, window) {
cancelMMI: function cancelMMI(window) {
debug("Cancel MMI");
if (!window) {
throw Components.Exception("Can't get window object",
@ -910,7 +882,7 @@ RILContentHelper.prototype = {
let request = Services.DOMRequest.createRequest(window);
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:CancelMMI", {
clientId: clientId,
clientId: 0,
data: {
requestId: requestId
}
@ -1104,7 +1076,7 @@ RILContentHelper.prototype = {
return request;
},
getCallForwardingOption: function getCallForwardingOption(clientId, window, reason) {
getCallForwardingOption: function getCallForwardingOption(window, reason) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1118,8 +1090,8 @@ RILContentHelper.prototype = {
return request;
}
cpmm.sendAsyncMessage("RIL:GetCallForwardingOptions", {
clientId: clientId,
cpmm.sendAsyncMessage("RIL:GetCallForwardingOption", {
clientId: 0,
data: {
requestId: requestId,
reason: reason
@ -1129,7 +1101,7 @@ RILContentHelper.prototype = {
return request;
},
setCallForwardingOption: function setCallForwardingOption(clientId, window, cfInfo) {
setCallForwardingOption: function setCallForwardingOption(window, cfInfo) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1145,8 +1117,8 @@ RILContentHelper.prototype = {
return request;
}
cpmm.sendAsyncMessage("RIL:SetCallForwardingOptions", {
clientId: clientId,
cpmm.sendAsyncMessage("RIL:SetCallForwardingOption", {
clientId: 0,
data: {
requestId: requestId,
active: cfInfo.active,
@ -1160,7 +1132,7 @@ RILContentHelper.prototype = {
return request;
},
getCallBarringOption: function getCallBarringOption(clientId, window, option) {
getCallBarringOption: function getCallBarringOption(window, option) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1169,14 +1141,14 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
if (DEBUG) debug("getCallBarringOption: " + JSON.stringify(option));
if (!this._isValidCallBarringOptions(option)) {
if (!this._isValidCallBarringOption(option)) {
this.dispatchFireRequestError(requestId,
RIL.GECKO_ERROR_INVALID_PARAMETER);
return request;
}
cpmm.sendAsyncMessage("RIL:GetCallBarringOptions", {
clientId: clientId,
cpmm.sendAsyncMessage("RIL:GetCallBarringOption", {
clientId: 0,
data: {
requestId: requestId,
program: option.program,
@ -1187,7 +1159,7 @@ RILContentHelper.prototype = {
return request;
},
setCallBarringOption: function setCallBarringOption(clientId, window, option) {
setCallBarringOption: function setCallBarringOption(window, option) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1196,14 +1168,14 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
if (DEBUG) debug("setCallBarringOption: " + JSON.stringify(option));
if (!this._isValidCallBarringOptions(option, true)) {
if (!this._isValidCallBarringOption(option, true)) {
this.dispatchFireRequestError(requestId,
RIL.GECKO_ERROR_INVALID_PARAMETER);
return request;
}
cpmm.sendAsyncMessage("RIL:SetCallBarringOptions", {
clientId: clientId,
cpmm.sendAsyncMessage("RIL:SetCallBarringOption", {
clientId: 0,
data: {
requestId: requestId,
program: option.program,
@ -1215,7 +1187,7 @@ RILContentHelper.prototype = {
return request;
},
changeCallBarringPassword: function changeCallBarringPassword(clientId, window, info) {
changeCallBarringPassword: function changeCallBarringPassword(window, info) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1233,14 +1205,14 @@ RILContentHelper.prototype = {
if (DEBUG) debug("changeCallBarringPassword: " + JSON.stringify(info));
info.requestId = requestId;
cpmm.sendAsyncMessage("RIL:ChangeCallBarringPassword", {
clientId: clientId,
clientId: 0,
data: info
});
return request;
},
getCallWaitingOption: function getCallWaitingOption(clientId, window) {
getCallWaitingOption: function getCallWaitingOption(window) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1248,8 +1220,8 @@ RILContentHelper.prototype = {
let request = Services.DOMRequest.createRequest(window);
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:GetCallWaitingOptions", {
clientId: clientId,
cpmm.sendAsyncMessage("RIL:GetCallWaitingOption", {
clientId: 0,
data: {
requestId: requestId
}
@ -1258,7 +1230,7 @@ RILContentHelper.prototype = {
return request;
},
setCallWaitingOption: function setCallWaitingOption(clientId, window, enabled) {
setCallWaitingOption: function setCallWaitingOption(window, enabled) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1266,8 +1238,8 @@ RILContentHelper.prototype = {
let request = Services.DOMRequest.createRequest(window);
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:SetCallWaitingOptions", {
clientId: clientId,
cpmm.sendAsyncMessage("RIL:SetCallWaitingOption", {
clientId: 0,
data: {
requestId: requestId,
enabled: enabled
@ -1277,7 +1249,7 @@ RILContentHelper.prototype = {
return request;
},
getCallingLineIdRestriction: function getCallingLineIdRestriction(clientId, window) {
getCallingLineIdRestriction: function getCallingLineIdRestriction(window) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1286,7 +1258,7 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:GetCallingLineIdRestriction", {
clientId: clientId,
clientId: 0,
data: {
requestId: requestId
}
@ -1296,7 +1268,7 @@ RILContentHelper.prototype = {
},
setCallingLineIdRestriction:
function setCallingLineIdRestriction(clientId, window, clirMode) {
function setCallingLineIdRestriction(window, clirMode) {
if (window == null) {
throw Components.Exception("Can't get window object",
@ -1306,7 +1278,7 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:SetCallingLineIdRestriction", {
clientId: clientId,
clientId: 0,
data: {
requestId: requestId,
clirMode: clirMode
@ -1316,7 +1288,7 @@ RILContentHelper.prototype = {
return request;
},
exitEmergencyCbMode: function exitEmergencyCbMode(clientId, window) {
exitEmergencyCbMode: function exitEmergencyCbMode(window) {
if (window == null) {
throw Components.Exception("Can't get window object",
Cr.NS_ERROR_UNEXPECTED);
@ -1325,7 +1297,7 @@ RILContentHelper.prototype = {
let requestId = this.getRequestId(request);
cpmm.sendAsyncMessage("RIL:ExitEmergencyCbMode", {
clientId: clientId,
clientId: 0,
data: {
requestId: requestId,
}
@ -1362,13 +1334,10 @@ RILContentHelper.prototype = {
return this.getVoicemailInfo().displayName;
},
registerListener: function registerListener(listenerType, clientId, listener) {
if (!this[listenerType]) {
return;
}
let listeners = this[listenerType][clientId];
registerListener: function registerListener(listenerType, listener) {
let listeners = this[listenerType];
if (!listeners) {
listeners = this[listenerType][clientId] = [];
listeners = this[listenerType] = [];
}
if (listeners.indexOf(listener) != -1) {
@ -1379,11 +1348,8 @@ RILContentHelper.prototype = {
if (DEBUG) debug("Registered " + listenerType + " listener: " + listener);
},
unregisterListener: function unregisterListener(listenerType, clientId, listener) {
if (!this[listenerType]) {
return;
}
let listeners = this[listenerType][clientId];
unregisterListener: function unregisterListener(listenerType, listener) {
let listeners = this[listenerType];
if (!listeners) {
return;
}
@ -1395,50 +1361,44 @@ RILContentHelper.prototype = {
}
},
registerMobileConnectionMsg: function registerMobileConnectionMsg(clientId, listener) {
registerMobileConnectionMsg: function registerMobileConnectionMsg(listener) {
debug("Registering for mobile connection related messages");
this.registerListener("_mobileConnectionListeners", clientId, listener);
this.registerListener("_mobileConnectionListeners", listener);
cpmm.sendAsyncMessage("RIL:RegisterMobileConnectionMsg");
},
unregisterMobileConnectionMsg: function unregisteMobileConnectionMsg(clientId, listener) {
this.unregisterListener("_mobileConnectionListeners", clientId, listener);
unregisterMobileConnectionMsg: function unregisteMobileConnectionMsg(listener) {
this.unregisterListener("_mobileConnectionListeners", listener);
},
registerVoicemailMsg: function registerVoicemailMsg(listener) {
debug("Registering for voicemail-related messages");
//TODO: Bug 814634 - WebVoicemail API: support multiple sim cards.
this.registerListener("_voicemailListeners", 0, listener);
this.registerListener("_voicemailListeners", listener);
cpmm.sendAsyncMessage("RIL:RegisterVoicemailMsg");
},
unregisterVoicemailMsg: function unregisteVoicemailMsg(listener) {
//TODO: Bug 814634 - WebVoicemail API: support multiple sim cards.
this.unregisterListener("_voicemailListeners", 0, listener);
this.unregisterListener("_voicemailListeners", listener);
},
registerCellBroadcastMsg: function registerCellBroadcastMsg(listener) {
debug("Registering for Cell Broadcast related messages");
//TODO: Bug 921326 - Cellbroadcast API: support multiple sim cards
this.registerListener("_cellBroadcastListeners", 0, listener);
this.registerListener("_cellBroadcastListeners", listener);
cpmm.sendAsyncMessage("RIL:RegisterCellBroadcastMsg");
},
unregisterCellBroadcastMsg: function unregisterCellBroadcastMsg(listener) {
//TODO: Bug 921326 - Cellbroadcast API: support multiple sim cards
this.unregisterListener("_cellBroadcastListeners", 0, listener);
this.unregisterListener("_cellBroadcastListeners", listener);
},
registerIccMsg: function registerIccMsg(listener) {
debug("Registering for ICC related messages");
//TODO: Bug 814637 - WebIccManager API: support multiple sim cards.
this.registerListener("_iccListeners", 0, listener);
this.registerListener("_iccListeners", listener);
cpmm.sendAsyncMessage("RIL:RegisterIccMsg");
},
unregisterIccMsg: function unregisterIccMsg(listener) {
//TODO: Bug 814637 - WebIccManager API: support multiple sim cards.
this.unregisterListener("_iccListeners", 0, listener);
this.unregisterListener("_iccListeners", listener);
},
// nsIObserver
@ -1518,43 +1478,35 @@ RILContentHelper.prototype = {
debug("Received message '" + msg.name + "': " + JSON.stringify(msg.json));
let data = msg.json.data;
let clientId = msg.json.clientId;
switch (msg.name) {
case "RIL:CardStateChanged":
if (this.rilContexts[clientId].cardState != data.cardState) {
this.rilContexts[clientId].cardState = data.cardState;
this._deliverEvent(clientId,
"_iccListeners",
if (this.rilContext.cardState != data.cardState) {
this.rilContext.cardState = data.cardState;
this._deliverEvent("_iccListeners",
"notifyCardStateChanged",
null);
}
break;
case "RIL:IccInfoChanged":
this.updateIccInfo(clientId, data);
this._deliverEvent(clientId,
"_iccListeners",
"notifyIccInfoChanged",
null);
this.updateIccInfo(data);
this._deliverEvent("_iccListeners", "notifyIccInfoChanged", null);
break;
case "RIL:VoiceInfoChanged":
this.updateConnectionInfo(data,
this.rilContexts[clientId].voiceConnectionInfo);
this._deliverEvent(clientId,
"_mobileConnectionListeners",
this.rilContext.voiceConnectionInfo);
this._deliverEvent("_mobileConnectionListeners",
"notifyVoiceChanged",
null);
break;
case "RIL:DataInfoChanged":
this.updateConnectionInfo(data,
this.rilContexts[clientId].dataConnectionInfo);
this._deliverEvent(clientId,
"_mobileConnectionListeners",
this.rilContext.dataConnectionInfo);
this._deliverEvent("_mobileConnectionListeners",
"notifyDataChanged",
null);
break;
case "RIL:OtaStatusChanged":
this._deliverEvent(clientId,
"_mobileConnectionListeners",
this._deliverEvent("_mobileConnectionListeners",
"notifyOtaStatusChanged",
[data]);
break;
@ -1562,18 +1514,18 @@ RILContentHelper.prototype = {
this.handleGetAvailableNetworks(data);
break;
case "RIL:NetworkSelectionModeChanged":
this.rilContexts[clientId].networkSelectionMode = data.mode;
this.rilContext.networkSelectionMode = data.mode;
break;
case "RIL:SelectNetwork":
this.handleSelectNetwork(clientId, data,
this.handleSelectNetwork(data,
RIL.GECKO_NETWORK_SELECTION_MANUAL);
break;
case "RIL:SelectNetworkAuto":
this.handleSelectNetwork(clientId, data,
this.handleSelectNetwork(data,
RIL.GECKO_NETWORK_SELECTION_AUTOMATIC);
break;
case "RIL:VoicemailNotification":
this.handleVoicemailNotification(clientId, data);
this.handleVoicemailNotification(data);
break;
case "RIL:VoicemailInfoChanged":
this.updateInfo(data, this.voicemailInfo);
@ -1608,8 +1560,7 @@ RILContentHelper.prototype = {
}
break;
case "RIL:USSDReceived":
this._deliverEvent(clientId,
"_mobileConnectionListeners",
this._deliverEvent("_mobileConnectionListeners",
"notifyUssdReceived",
[data.message, data.sessionEnded]);
break;
@ -1618,11 +1569,11 @@ RILContentHelper.prototype = {
this.handleSendCancelMMI(data);
break;
case "RIL:StkCommand":
this._deliverEvent(clientId, "_iccListeners", "notifyStkCommand",
this._deliverEvent("_iccListeners", "notifyStkCommand",
[JSON.stringify(data)]);
break;
case "RIL:StkSessionEnd":
this._deliverEvent(clientId, "_iccListeners", "notifyStkSessionEnd", null);
this._deliverEvent("_iccListeners", "notifyStkSessionEnd", null);
break;
case "RIL:IccOpenChannel":
this.handleSimpleRequest(data.requestId, data.errorMsg,
@ -1641,35 +1592,34 @@ RILContentHelper.prototype = {
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:DataError":
this.updateConnectionInfo(data, this.rilContexts[clientId].dataConnectionInfo);
this._deliverEvent(clientId, "_mobileConnectionListeners", "notifyDataError",
this.updateConnectionInfo(data, this.rilContext.dataConnectionInfo);
this._deliverEvent("_mobileConnectionListeners", "notifyDataError",
[data.errorMsg]);
break;
case "RIL:GetCallForwardingOptions":
this.handleGetCallForwardingOptions(data);
case "RIL:GetCallForwardingOption":
this.handleGetCallForwardingOption(data);
break;
case "RIL:SetCallForwardingOptions":
case "RIL:SetCallForwardingOption":
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:GetCallBarringOptions":
this.handleGetCallBarringOptions(data);
case "RIL:GetCallBarringOption":
this.handleGetCallBarringOption(data);
break;
case "RIL:SetCallBarringOptions":
case "RIL:SetCallBarringOption":
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:ChangeCallBarringPassword":
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:GetCallWaitingOptions":
case "RIL:GetCallWaitingOption":
this.handleSimpleRequest(data.requestId, data.errorMsg,
data.enabled);
break;
case "RIL:SetCallWaitingOptions":
case "RIL:SetCallWaitingOption":
this.handleSimpleRequest(data.requestId, data.errorMsg, null);
break;
case "RIL:CfStateChanged":
this._deliverEvent(clientId,
"_mobileConnectionListeners",
this._deliverEvent("_mobileConnectionListeners",
"notifyCFStateChange",
[data.success, data.action,
data.reason, data.number,
@ -1683,8 +1633,7 @@ RILContentHelper.prototype = {
break;
case "RIL:CellBroadcastReceived": {
let message = new CellBroadcastMessage(data);
this._deliverEvent(clientId,
"_cellBroadcastListeners",
this._deliverEvent("_cellBroadcastListeners",
"notifyMessageReceived",
[message]);
break;
@ -1700,8 +1649,7 @@ RILContentHelper.prototype = {
this.handleExitEmergencyCbMode(data);
break;
case "RIL:EmergencyCbModeChanged":
this._deliverEvent(clientId,
"_mobileConnectionListeners",
this._deliverEvent("_mobileConnectionListeners",
"notifyEmergencyCbModeChanged",
[data.active, data.timeoutMs]);
break;
@ -1742,9 +1690,9 @@ RILContentHelper.prototype = {
this.fireRequestSuccess(message.requestId, networks);
},
handleSelectNetwork: function handleSelectNetwork(clientId, message, mode) {
this._selectingNetworks[clientId] = null;
this.rilContexts[clientId].networkSelectionMode = mode;
handleSelectNetwork: function handleSelectNetwork(message, mode) {
this._selectingNetwork = null;
this.rilContext.networkSelectionMode = mode;
if (message.errorMsg) {
this.fireRequestError(message.requestId, message.errorMsg);
@ -1793,8 +1741,7 @@ RILContentHelper.prototype = {
ObjectWrapper.wrap(result, window));
},
handleVoicemailNotification: function handleVoicemailNotification(clientId, message) {
// TODO: Bug 818352 - B2G Multi-SIM: voicemail - add subscription id in nsIRILContentHelper
handleVoicemailNotification: function handleVoicemailNotification(message) {
let changed = false;
if (!this.voicemailStatus) {
this.voicemailStatus = new VoicemailStatus();
@ -1824,8 +1771,7 @@ RILContentHelper.prototype = {
}
if (changed) {
this._deliverEvent(clientId,
"_voicemailListeners",
this._deliverEvent("_voicemailListeners",
"notifyStatusChanged",
[this.voicemailStatus]);
}
@ -1840,7 +1786,7 @@ RILContentHelper.prototype = {
}
},
handleGetCallForwardingOptions: function handleGetCallForwardingOptions(message) {
handleGetCallForwardingOption: function handleGetCallForwardingOption(message) {
if (message.errorMsg) {
this.fireRequestError(message.requestId, message.errorMsg);
return;
@ -1850,12 +1796,12 @@ RILContentHelper.prototype = {
this.fireRequestSuccess(message.requestId, message.rules);
},
handleGetCallBarringOptions: function handleGetCallBarringOptions(message) {
handleGetCallBarringOption: function handleGetCallBarringOption(message) {
if (!message.success) {
this.fireRequestError(message.requestId, message.errorMsg);
} else {
let options = new CallBarringOptions(message);
this.fireRequestSuccess(message.requestId, options);
let option = new CallBarringOption(message);
this.fireRequestSuccess(message.requestId, option);
}
},
@ -1931,11 +1877,8 @@ RILContentHelper.prototype = {
}
},
_deliverEvent: function _deliverEvent(clientId, listenerType, name, args) {
if (!this[listenerType]) {
return;
}
let thisListeners = this[listenerType][clientId];
_deliverEvent: function _deliverEvent(listenerType, name, args) {
let thisListeners = this[listenerType];
if (!thisListeners) {
return;
}
@ -2006,18 +1949,18 @@ RILContentHelper.prototype = {
},
/**
* Helper for guarding us against invalid options for call barring.
* Helper for guarding us against invalid option for call barring.
*/
_isValidCallBarringOptions:
function _isValidCallBarringOptions(options, usedForSetting) {
if (!options ||
options.serviceClass == null ||
!this._isValidCallBarringProgram(options.program)) {
_isValidCallBarringOption:
function _isValidCallBarringOption(option, usedForSetting) {
if (!option ||
option.serviceClass == null ||
!this._isValidCallBarringProgram(option.program)) {
return false;
}
// For setting callbarring options, |enabled| and |password| are required.
if (usedForSetting && (options.enabled == null || options.password == null)) {
// For setting callbarring option, |enabled| and |password| are required.
if (usedForSetting && (option.enabled == null || option.password == null)) {
return false;
}

View File

@ -90,13 +90,13 @@ const RIL_IPC_MOBILECONNECTION_MSG_NAMES = [
"RIL:SendMMI",
"RIL:CancelMMI",
"RIL:RegisterMobileConnectionMsg",
"RIL:SetCallForwardingOptions",
"RIL:GetCallForwardingOptions",
"RIL:SetCallBarringOptions",
"RIL:GetCallBarringOptions",
"RIL:SetCallForwardingOption",
"RIL:GetCallForwardingOption",
"RIL:SetCallBarringOption",
"RIL:GetCallBarringOption",
"RIL:ChangeCallBarringPassword",
"RIL:SetCallWaitingOptions",
"RIL:GetCallWaitingOptions",
"RIL:SetCallWaitingOption",
"RIL:GetCallWaitingOption",
"RIL:SetCallingLineIdRestriction",
"RIL:GetCallingLineIdRestriction",
"RIL:SetRoamingPreference",
@ -935,25 +935,25 @@ RadioInterface.prototype = {
case "RIL:UpdateIccContact":
this.workerMessenger.sendWithIPCMessage(msg, "updateICCContact");
break;
case "RIL:SetCallForwardingOptions":
this.setCallForwardingOptions(msg.target, msg.json.data);
case "RIL:SetCallForwardingOption":
this.setCallForwardingOption(msg.target, msg.json.data);
break;
case "RIL:GetCallForwardingOptions":
case "RIL:GetCallForwardingOption":
this.workerMessenger.sendWithIPCMessage(msg, "queryCallForwardStatus");
break;
case "RIL:SetCallBarringOptions":
case "RIL:SetCallBarringOption":
this.workerMessenger.sendWithIPCMessage(msg, "setCallBarring");
break;
case "RIL:GetCallBarringOptions":
case "RIL:GetCallBarringOption":
this.workerMessenger.sendWithIPCMessage(msg, "queryCallBarringStatus");
break;
case "RIL:ChangeCallBarringPassword":
this.workerMessenger.sendWithIPCMessage(msg, "changeCallBarringPassword");
break;
case "RIL:SetCallWaitingOptions":
case "RIL:SetCallWaitingOption":
this.workerMessenger.sendWithIPCMessage(msg, "setCallWaiting");
break;
case "RIL:GetCallWaitingOptions":
case "RIL:GetCallWaitingOption":
this.workerMessenger.sendWithIPCMessage(msg, "queryCallWaiting");
break;
case "RIL:SetCallingLineIdRestriction":
@ -2406,12 +2406,12 @@ RadioInterface.prototype = {
}).bind(this));
},
setCallForwardingOptions: function setCallForwardingOptions(target, message) {
if (DEBUG) this.debug("setCallForwardingOptions: " + JSON.stringify(message));
setCallForwardingOption: function setCallForwardingOption(target, message) {
if (DEBUG) this.debug("setCallForwardingOption: " + JSON.stringify(message));
message.serviceClass = RIL.ICC_SERVICE_CLASS_VOICE;
this.workerMessenger.send("setCallForward", message, (function(response) {
this._sendCfStateChanged(response);
target.sendAsyncMessage("RIL:SetCallForwardingOptions", {
target.sendAsyncMessage("RIL:SetCallForwardingOption", {
clientId: this.clientId,
data: response
});

View File

@ -14,7 +14,7 @@ DIRS += [
if CONFIG['MOZ_B2G_RIL']:
DIRS += ['ril']
if CONFIG['MOZ_B2G_BT']:
if CONFIG['MOZ_B2G_BT_BLUEZ']:
DIRS += ['dbus']
if CONFIG['MOZ_B2G_RIL'] or CONFIG['MOZ_B2G_BT']:

View File

@ -12,7 +12,7 @@
#include <sys/types.h>
#include <sys/un.h>
#include <netinet/in.h>
#ifdef MOZ_B2G_BT
#ifdef MOZ_B2G_BT_BLUEZ
#include <bluetooth/bluetooth.h>
#include <bluetooth/sco.h>
#include <bluetooth/l2cap.h>
@ -31,7 +31,7 @@ union sockaddr_any {
sockaddr_un un;
sockaddr_in in;
sockaddr_in6 in6;
#ifdef MOZ_B2G_BT
#ifdef MOZ_B2G_BT_BLUEZ
sockaddr_sco sco;
sockaddr_rc rc;
sockaddr_l2 l2;

View File

@ -13,7 +13,7 @@ var InputWidgetHelper = {
handleClick: function(aTarget) {
// if we're busy looking at a InputWidget we want to eat any clicks that
// come to us, but not to process them
if (this._uiBusy || !this._isValidInput(aTarget))
if (this._uiBusy || !this.hasInputWidget(aTarget))
return;
this._uiBusy = true;
@ -60,7 +60,7 @@ var InputWidgetHelper = {
}).bind(this));
},
_isValidInput: function(aElement) {
hasInputWidget: function(aElement) {
if (!aElement instanceof HTMLInputElement)
return false;

View File

@ -286,7 +286,7 @@ var SelectionHandler = {
this._initTargetInfo(aElement);
this._contentWindow.addEventListener("keydown", this, false);
this._contentWindow.addEventListener("blur", this, false);
this._contentWindow.addEventListener("blur", this, true);
this._activeType = this.TYPE_CURSOR;
this._positionHandles();

View File

@ -4308,8 +4308,9 @@ var BrowserEventHandler = {
this._sendMouseEvent("mousedown", element, x, y);
this._sendMouseEvent("mouseup", element, x, y);
// See if its an input element, and it isn't disabled
// See if its an input element, and it isn't disabled, nor handled by Android native dialog
if (!element.disabled &&
!InputWidgetHelper.hasInputWidget(element) &&
((element instanceof HTMLInputElement && element.mozIsTextField(false)) ||
(element instanceof HTMLTextAreaElement)))
SelectionHandler.attachCaret(element);

View File

@ -89,7 +89,7 @@ ifdef MOZ_B2G_RIL #{
STATIC_LIBS += mozril_s
endif #}
ifdef MOZ_B2G_BT #{
ifdef MOZ_B2G_BT_BLUEZ #{
STATIC_LIBS += mozdbus_s
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
OS_LIBS += -ldbus

View File

@ -12,24 +12,15 @@
* implementation of this interface for non-Windows systems, for testing and
* development purposes only.
*/
[scriptable, uuid(25524bde-8b30-4b49-8d67-7070c790aada)]
[scriptable, uuid(496b4450-5757-40f7-aeb9-a958ae86dbd1)]
interface nsIWinMetroUtils : nsISupports
{
/* return constants for the handPreference property */
const long handPreferenceLeft = 0;
const long handPreferenceRight = 1;
/**
* Determine if the current browser is running in the metro immersive
* environment.
*/
readonly attribute boolean immersive;
/**
* Determine if the user prefers left handed or right handed input.
*/
readonly attribute long handPreference;
/**
* Determine the activation URI
*/

View File

@ -384,27 +384,6 @@ nsWinMetroUtils::GetImmersive(bool *aImersive)
return NS_OK;
}
NS_IMETHODIMP
nsWinMetroUtils::GetHandPreference(int32_t *aHandPreference)
{
if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop) {
*aHandPreference = nsIWinMetroUtils::handPreferenceRight;
return NS_OK;
}
ComPtr<IUISettings> uiSettings;
AssertRetHRESULT(ActivateGenericInstance(RuntimeClass_Windows_UI_ViewManagement_UISettings, uiSettings), NS_ERROR_UNEXPECTED);
HandPreference value;
uiSettings->get_HandPreference(&value);
if (value == HandPreference::HandPreference_LeftHanded)
*aHandPreference = nsIWinMetroUtils::handPreferenceLeft;
else
*aHandPreference = nsIWinMetroUtils::handPreferenceRight;
return NS_OK;
}
NS_IMETHODIMP
nsWinMetroUtils::GetActivationURI(nsAString &aActivationURI)
{