зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound
This commit is contained in:
Коммит
ba00ae5790
|
@ -9053,7 +9053,14 @@ XPCOMUtils.defineLazyGetter(Scratchpad, "ScratchpadManager", function() {
|
|||
|
||||
var StyleEditor = {
|
||||
prefEnabledName: "devtools.styleeditor.enabled",
|
||||
openChrome: function SE_openChrome()
|
||||
/**
|
||||
* Opens the style editor. If the UI is already open, it will be focused.
|
||||
*
|
||||
* @param {CSSStyleSheet} [aSelectedStyleSheet] default Stylesheet.
|
||||
* @param {Number} [aLine] Line to which the caret should be moved (one-indexed).
|
||||
* @param {Number} [aCol] Column to which the caret should be moved (one-indexed).
|
||||
*/
|
||||
openChrome: function SE_openChrome(aSelectedStyleSheet, aLine, aCol)
|
||||
{
|
||||
const CHROME_URL = "chrome://browser/content/styleeditor.xul";
|
||||
const CHROME_WINDOW_TYPE = "Tools:StyleEditor";
|
||||
|
@ -9067,14 +9074,23 @@ var StyleEditor = {
|
|||
while (enumerator.hasMoreElements()) {
|
||||
var win = enumerator.getNext();
|
||||
if (win.styleEditorChrome.contentWindowID == contentWindowID) {
|
||||
if (aSelectedStyleSheet) {
|
||||
win.styleEditorChrome.selectStyleSheet(aSelectedStyleSheet, aLine, aCol);
|
||||
}
|
||||
win.focus();
|
||||
return win;
|
||||
}
|
||||
}
|
||||
|
||||
let args = {
|
||||
contentWindow: contentWindow,
|
||||
selectedStyleSheet: aSelectedStyleSheet,
|
||||
line: aLine,
|
||||
col: aCol
|
||||
};
|
||||
args.wrappedJSObject = args;
|
||||
let chromeWindow = Services.ww.openWindow(null, CHROME_URL, "_blank",
|
||||
CHROME_WINDOW_FLAGS,
|
||||
contentWindow);
|
||||
CHROME_WINDOW_FLAGS, args);
|
||||
chromeWindow.focus();
|
||||
return chromeWindow;
|
||||
}
|
||||
|
|
|
@ -1371,7 +1371,8 @@
|
|||
|
||||
// pretend the user typed this so it'll be available till
|
||||
// the document successfully loads
|
||||
b.userTypedValue = aURI;
|
||||
if (!isBlankPageURL(aURI))
|
||||
b.userTypedValue = aURI;
|
||||
|
||||
let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
|
||||
if (aAllowThirdPartyFixup)
|
||||
|
@ -1563,15 +1564,26 @@
|
|||
<parameter name="aCloseWindowFastpath"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (aTab.closing || this._windowIsClosing)
|
||||
if (aTab.closing ||
|
||||
aTab._pendingPermitUnload ||
|
||||
this._windowIsClosing)
|
||||
return false;
|
||||
|
||||
var browser = this.getBrowserForTab(aTab);
|
||||
|
||||
if (!aTabWillBeMoved) {
|
||||
let ds = browser.docShell;
|
||||
if (ds && ds.contentViewer && !ds.contentViewer.permitUnload())
|
||||
return false;
|
||||
if (ds && ds.contentViewer) {
|
||||
// We need to block while calling permitUnload() because it
|
||||
// processes the event queue and may lead to another removeTab()
|
||||
// call before permitUnload() even returned.
|
||||
aTab._pendingPermitUnload = true;
|
||||
let permitUnload = ds.contentViewer.permitUnload();
|
||||
delete aTab._pendingPermitUnload;
|
||||
|
||||
if (!permitUnload)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var closeWindow = false;
|
||||
|
|
|
@ -72,6 +72,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_dbg_pause-resume.js \
|
||||
browser_dbg_update-editor-mode.js \
|
||||
browser_dbg_select-line.js \
|
||||
browser_dbg_clean-exit.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Test that closing a tab with the debugger in a paused state exits cleanly.
|
||||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
|
||||
const DEBUGGER_TAB_URL = "http://example.com/browser/browser/devtools/" +
|
||||
"debugger/test/" +
|
||||
"browser_dbg_debuggerstatement.html";
|
||||
|
||||
function test() {
|
||||
debug_tab_pane(DEBUGGER_TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
testCleanExit();
|
||||
});
|
||||
}
|
||||
|
||||
function testCleanExit() {
|
||||
gPane.activeThread.addOneTimeListener("framesadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: function() {
|
||||
is(gDebugger.StackFrames.activeThread.paused, true,
|
||||
"Should be paused after the debugger statement.");
|
||||
|
||||
gPane._client.addOneTimeListener("tabDetached", function () {
|
||||
finish();
|
||||
});
|
||||
removeTab(gTab);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gTab.linkedBrowser.contentWindow.wrappedJSObject.runDebuggerStatement();
|
||||
}
|
|
@ -763,6 +763,9 @@ InspectorUI.prototype = {
|
|||
this.boundRuleViewChanged = this.ruleViewChanged.bind(this);
|
||||
this.ruleView.element.addEventListener("CssRuleViewChanged",
|
||||
this.boundRuleViewChanged);
|
||||
this.cssRuleViewBoundCSSLinkClicked = this.ruleViewCSSLinkClicked.bind(this);
|
||||
this.ruleView.element.addEventListener("CssRuleViewCSSLinkClicked",
|
||||
this.cssRuleViewBoundCSSLinkClicked);
|
||||
|
||||
doc.documentElement.appendChild(this.ruleView.element);
|
||||
this.ruleView.highlight(this.selection);
|
||||
|
@ -800,6 +803,30 @@ InspectorUI.prototype = {
|
|||
this.nodeChanged(this.ruleViewObject);
|
||||
},
|
||||
|
||||
/**
|
||||
* When a css link is clicked this method is called in order to either:
|
||||
* 1. Open the link in view source (for element style attributes)
|
||||
* 2. Open the link in the style editor
|
||||
*
|
||||
* @param aEvent The event containing the style rule to act on
|
||||
*/
|
||||
ruleViewCSSLinkClicked: function(aEvent)
|
||||
{
|
||||
if (!this.chromeWin) {
|
||||
return;
|
||||
}
|
||||
|
||||
let rule = aEvent.detail.rule;
|
||||
let styleSheet = rule.sheet;
|
||||
|
||||
if (styleSheet) {
|
||||
this.chromeWin.StyleEditor.openChrome(styleSheet, rule.ruleLine);
|
||||
} else {
|
||||
let href = rule.elementStyle.element.ownerDocument.location.href;
|
||||
this.chromeWin.openUILinkIn("view-source:" + href, "window");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the rule view.
|
||||
*/
|
||||
|
@ -811,6 +838,8 @@ InspectorUI.prototype = {
|
|||
if (this.ruleView) {
|
||||
this.ruleView.element.removeEventListener("CssRuleViewChanged",
|
||||
this.boundRuleViewChanged);
|
||||
this.ruleView.element.removeEventListener("CssRuleViewCSSLinkClicked",
|
||||
this.cssRuleViewBoundCSSLinkClicked);
|
||||
delete boundRuleViewChanged;
|
||||
this.ruleView.clear();
|
||||
delete this.ruleView;
|
||||
|
|
|
@ -78,6 +78,9 @@ const ORION_EVENTS = {
|
|||
Selection: "Selection",
|
||||
Focus: "Focus",
|
||||
Blur: "Blur",
|
||||
MouseOver: "MouseOver",
|
||||
MouseOut: "MouseOut",
|
||||
MouseMove: "MouseMove",
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -161,6 +161,30 @@ SourceEditor.EVENTS = {
|
|||
* The blur event is fired when the editor goes out of focus.
|
||||
*/
|
||||
BLUR: "Blur",
|
||||
|
||||
/**
|
||||
* The MouseMove event is sent when the user moves the mouse over a line
|
||||
* annotation. The event object properties:
|
||||
* - event - the DOM mousemove event object.
|
||||
* - x and y - the mouse coordinates relative to the document being edited.
|
||||
*/
|
||||
MOUSE_MOVE: "MouseMove",
|
||||
|
||||
/**
|
||||
* The MouseOver event is sent when the mouse pointer enters a line
|
||||
* annotation. The event object properties:
|
||||
* - event - the DOM mouseover event object.
|
||||
* - x and y - the mouse coordinates relative to the document being edited.
|
||||
*/
|
||||
MOUSE_OVER: "MouseOver",
|
||||
|
||||
/**
|
||||
* This MouseOut event is sent when the mouse pointer exits a line
|
||||
* annotation. The event object properties:
|
||||
* - event - the DOM mouseout event object.
|
||||
* - x and y - the mouse coordinates relative to the document being edited.
|
||||
*/
|
||||
MOUSE_OUT: "MouseOut",
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -55,6 +55,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_bug687160_line_api.js \
|
||||
browser_bug650345_find.js \
|
||||
browser_bug703692_focus_blur.js \
|
||||
browser_bug725388_mouse_events.js \
|
||||
head.js \
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
let tempScope = {};
|
||||
Cu.import("resource:///modules/source-editor.jsm", tempScope);
|
||||
let SourceEditor = tempScope.SourceEditor;
|
||||
|
||||
let testWin;
|
||||
let editor;
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
const windowUrl = "data:text/xml,<?xml version='1.0'?>" +
|
||||
"<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'" +
|
||||
" title='Test for bug 725388' width='600' height='500'><hbox flex='1'/></window>";
|
||||
const windowFeatures = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
|
||||
|
||||
testWin = Services.ww.openWindow(null, windowUrl, "_blank", windowFeatures, null);
|
||||
testWin.addEventListener("load", function onWindowLoad() {
|
||||
testWin.removeEventListener("load", onWindowLoad, false);
|
||||
waitForFocus(initEditor, testWin);
|
||||
}, false);
|
||||
}
|
||||
|
||||
function initEditor()
|
||||
{
|
||||
let hbox = testWin.document.querySelector("hbox");
|
||||
|
||||
editor = new SourceEditor();
|
||||
editor.init(hbox, {}, editorLoaded);
|
||||
}
|
||||
|
||||
function editorLoaded()
|
||||
{
|
||||
let text = "BrowserBug - 725388";
|
||||
editor.setText(text);
|
||||
|
||||
let target = editor.editorElement;
|
||||
let targetWin = target.ownerDocument.defaultView;
|
||||
|
||||
let mMoveHandler = function(aEvent) {
|
||||
editor.removeEventListener(SourceEditor.EVENTS.MOUSE_MOVE, mMoveHandler);
|
||||
|
||||
is(aEvent.event.type, "mousemove", "MouseMove event fired.");
|
||||
|
||||
editor.addEventListener(SourceEditor.EVENTS.MOUSE_OVER, mOverHandler);
|
||||
waitForFocus(function() {
|
||||
EventUtils.synthesizeMouse(target, 10, 10, {type: "mouseover"},
|
||||
targetWin);
|
||||
});
|
||||
};
|
||||
|
||||
let mOverHandler = function(aEvent) {
|
||||
editor.removeEventListener(SourceEditor.EVENTS.MOUSE_OVER, mOverHandler);
|
||||
|
||||
is(aEvent.event.type, "mouseover", "MouseOver event fired.");
|
||||
|
||||
editor.addEventListener(SourceEditor.EVENTS.MOUSE_OUT, mOutHandler);
|
||||
waitForFocus(function() {
|
||||
EventUtils.synthesizeMouse(target, -10, -10, {type: "mouseout"},
|
||||
targetWin);
|
||||
}, targetWin);
|
||||
};
|
||||
|
||||
let mOutHandler = function(aEvent) {
|
||||
editor.removeEventListener(SourceEditor.EVENTS.MOUSE_OUT, mOutHandler);
|
||||
|
||||
is(aEvent.event.type, "mouseout", "MouseOut event fired.");
|
||||
executeSoon(testEnd);
|
||||
};
|
||||
|
||||
editor.addEventListener(SourceEditor.EVENTS.MOUSE_MOVE, mMoveHandler);
|
||||
|
||||
editor.focus();
|
||||
waitForFocus(function() {
|
||||
EventUtils.synthesizeMouse(target, 1, 1, {type: "mousemove"},
|
||||
targetWin);
|
||||
}, targetWin);
|
||||
}
|
||||
|
||||
function testEnd()
|
||||
{
|
||||
if (editor) {
|
||||
editor.destroy();
|
||||
}
|
||||
if (testWin) {
|
||||
testWin.close();
|
||||
}
|
||||
testWin = editor = null;
|
||||
|
||||
waitForFocus(finish, window);
|
||||
}
|
|
@ -146,7 +146,7 @@ StyleEditor.prototype = {
|
|||
*/
|
||||
get styleSheet()
|
||||
{
|
||||
assert(this._styleSheet, "StyleSheet must be loaded first.")
|
||||
assert(this._styleSheet, "StyleSheet must be loaded first.");
|
||||
return this._styleSheet;
|
||||
},
|
||||
|
||||
|
@ -921,9 +921,11 @@ StyleEditor.prototype = {
|
|||
aArgs.unshift(this);
|
||||
}
|
||||
|
||||
// copy the list of listeners to allow adding/removing listeners in handlers
|
||||
let listeners = this._actionListeners.concat();
|
||||
// trigger all listeners that have this action handler
|
||||
for (let i = 0; i < this._actionListeners.length; ++i) {
|
||||
let listener = this._actionListeners[i];
|
||||
for (let i = 0; i < listeners.length; ++i) {
|
||||
let listener = listeners[i];
|
||||
let actionHandler = listener["on" + aName];
|
||||
if (actionHandler) {
|
||||
actionHandler.apply(listener, aArgs);
|
||||
|
|
|
@ -270,9 +270,11 @@ StyleEditorChrome.prototype = {
|
|||
aArgs.unshift(this);
|
||||
}
|
||||
|
||||
// trigger all listeners that have this named handler
|
||||
for (let i = 0; i < this._listeners.length; ++i) {
|
||||
let listener = this._listeners[i];
|
||||
// copy the list of listeners to allow adding/removing listeners in handlers
|
||||
let listeners = this._listeners.concat();
|
||||
// trigger all listeners that have this named handler.
|
||||
for (let i = 0; i < listeners.length; i++) {
|
||||
let listener = listeners[i];
|
||||
let handler = listener["on" + aName];
|
||||
if (handler) {
|
||||
handler.apply(listener, aArgs);
|
||||
|
@ -329,10 +331,10 @@ StyleEditorChrome.prototype = {
|
|||
{
|
||||
this._resetChrome();
|
||||
|
||||
this._document.title = _("chromeWindowTitle",
|
||||
this.contentDocument.title || this.contentDocument.location.href);
|
||||
|
||||
let document = this.contentDocument;
|
||||
this._document.title = _("chromeWindowTitle",
|
||||
document.title || document.location.href);
|
||||
|
||||
for (let i = 0; i < document.styleSheets.length; ++i) {
|
||||
let styleSheet = document.styleSheets[i];
|
||||
|
||||
|
@ -352,6 +354,79 @@ StyleEditorChrome.prototype = {
|
|||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* selects a stylesheet and optionally moves the cursor to a selected line
|
||||
*
|
||||
* @param {CSSStyleSheet} [aSheet]
|
||||
* Stylesheet that should be selected. If a stylesheet is not passed
|
||||
* and the editor is not initialized we focus the first stylesheet. If
|
||||
* a stylesheet is not passed and the editor is initialized we ignore
|
||||
* the call.
|
||||
* @param {Number} [aLine]
|
||||
* Line to which the caret should be moved (one-indexed).
|
||||
* @param {Number} [aCol]
|
||||
* Column to which the caret should be moved (one-indexed).
|
||||
*/
|
||||
selectStyleSheet: function SEC_selectSheet(aSheet, aLine, aCol)
|
||||
{
|
||||
let select = function DEC_select(aEditor) {
|
||||
let summary = aSheet ? this.getSummaryElementForEditor(aEditor)
|
||||
: this._view.getSummaryElementByOrdinal(0);
|
||||
let setCaret = false;
|
||||
|
||||
if (aLine || aCol) {
|
||||
aLine = aLine || 1;
|
||||
aCol = aCol || 1;
|
||||
setCaret = true;
|
||||
}
|
||||
if (!aEditor.sourceEditor) {
|
||||
// If a line or column was specified we move the caret appropriately.
|
||||
if (setCaret) {
|
||||
aEditor.addActionListener({
|
||||
onAttach: function SEC_selectSheet_onAttach()
|
||||
{
|
||||
aEditor.removeActionListener(this);
|
||||
aEditor.sourceEditor.setCaretPosition(aLine - 1, aCol - 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
this._view.activeSummary = summary;
|
||||
} else {
|
||||
this._view.activeSummary = summary;
|
||||
|
||||
// If a line or column was specified we move the caret appropriately.
|
||||
if (setCaret) {
|
||||
aEditor.sourceEditor.setCaretPosition(aLine - 1, aCol - 1);
|
||||
}
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
if (!this.editors.length) {
|
||||
// We are in the main initialization phase so we wait for the editor
|
||||
// containing the target stylesheet to be added and select the target
|
||||
// stylesheet, optionally moving the cursor to a selected line.
|
||||
this.addChromeListener({
|
||||
onEditorAdded: function SEC_selectSheet_onEditorAdded(aChrome, aEditor) {
|
||||
if ((!aSheet && aEditor.styleSheetIndex == 0) ||
|
||||
aEditor.styleSheet == aSheet) {
|
||||
aChrome.removeChromeListener(this);
|
||||
select(aEditor);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (aSheet) {
|
||||
// We are already initialized and a stylesheet has been specified. Here
|
||||
// we iterate through the editors and select the one containing the target
|
||||
// stylesheet, optionally moving the cursor to a selected line.
|
||||
for each (let editor in this.editors) {
|
||||
if (editor.styleSheet == aSheet) {
|
||||
select(editor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Disable all UI, effectively making editors read-only.
|
||||
* This is automatically called when no content window is attached.
|
||||
|
@ -455,9 +530,8 @@ StyleEditorChrome.prototype = {
|
|||
}
|
||||
}, false);
|
||||
|
||||
// autofocus the first or new stylesheet
|
||||
if (editor.styleSheetIndex == 0 ||
|
||||
editor.hasFlag(StyleEditorFlags.NEW)) {
|
||||
// autofocus new stylesheets
|
||||
if (editor.hasFlag(StyleEditorFlags.NEW)) {
|
||||
this._view.activeSummary = aSummary;
|
||||
}
|
||||
|
||||
|
|
|
@ -132,8 +132,10 @@
|
|||
<xul:script type="application/javascript"><![CDATA[
|
||||
Components.utils.import("resource:///modules/devtools/StyleEditorChrome.jsm");
|
||||
let chromeRoot = document.getElementById("style-editor-chrome");
|
||||
let contentWindow = window.arguments[0];
|
||||
let args = window.arguments[0].wrappedJSObject;
|
||||
let contentWindow = args.contentWindow;
|
||||
let chrome = new StyleEditorChrome(chromeRoot, contentWindow);
|
||||
chrome.selectStyleSheet(args.selectedStyleSheet, args.line, args.col);
|
||||
window.styleEditorChrome = chrome;
|
||||
]]></xul:script>
|
||||
</xul:window>
|
||||
|
|
|
@ -51,6 +51,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_styleeditor_init.js \
|
||||
browser_styleeditor_loading.js \
|
||||
browser_styleeditor_new.js \
|
||||
browser_styleeditor_passedinsheet.js \
|
||||
browser_styleeditor_pretty.js \
|
||||
browser_styleeditor_readonly.js \
|
||||
browser_styleeditor_reopen.js \
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const TESTCASE_URI = TEST_BASE + "simple.html";
|
||||
const LINE = 6;
|
||||
const COL = 2;
|
||||
|
||||
let editor = null;
|
||||
let sheet = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function () {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
run();
|
||||
}, true);
|
||||
content.location = TESTCASE_URI;
|
||||
}
|
||||
|
||||
function run()
|
||||
{
|
||||
sheet = content.document.styleSheets[1];
|
||||
launchStyleEditorChrome(function attachListeners(aChrome) {
|
||||
aChrome.addChromeListener({
|
||||
onEditorAdded: checkSourceEditor
|
||||
});
|
||||
}, sheet, LINE, COL);
|
||||
}
|
||||
|
||||
function checkSourceEditor(aChrome, aEditor)
|
||||
{
|
||||
if (!aEditor.sourceEditor) {
|
||||
aEditor.addActionListener({
|
||||
onAttach: function (aEditor) {
|
||||
aEditor.removeActionListener(this);
|
||||
validate(aEditor);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
validate(aEditor);
|
||||
}
|
||||
}
|
||||
|
||||
function validate(aEditor)
|
||||
{
|
||||
info("validating style editor");
|
||||
let sourceEditor = aEditor.sourceEditor;
|
||||
let caretPosition = sourceEditor.getCaretPosition();
|
||||
is(caretPosition.line, LINE - 1, "caret row is correct"); // index based
|
||||
is(caretPosition.col, COL - 1, "caret column is correct");
|
||||
is(aEditor.styleSheet, sheet, "loaded stylesheet matches document stylesheet");
|
||||
finishUp();
|
||||
}
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
editor = sheet = null;
|
||||
finish();
|
||||
}
|
|
@ -19,9 +19,9 @@ function cleanup()
|
|||
}
|
||||
}
|
||||
|
||||
function launchStyleEditorChrome(aCallback)
|
||||
function launchStyleEditorChrome(aCallback, aSheet, aLine, aCol)
|
||||
{
|
||||
gChromeWindow = StyleEditor.openChrome();
|
||||
gChromeWindow = StyleEditor.openChrome(aSheet, aLine, aCol);
|
||||
if (gChromeWindow.document.readyState != "complete") {
|
||||
gChromeWindow.addEventListener("load", function onChromeLoad() {
|
||||
gChromeWindow.removeEventListener("load", onChromeLoad, true);
|
||||
|
@ -34,12 +34,12 @@ function launchStyleEditorChrome(aCallback)
|
|||
}
|
||||
}
|
||||
|
||||
function addTabAndLaunchStyleEditorChromeWhenLoaded(aCallback)
|
||||
function addTabAndLaunchStyleEditorChromeWhenLoaded(aCallback, aSheet, aLine, aCol)
|
||||
{
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
launchStyleEditorChrome(aCallback);
|
||||
launchStyleEditorChrome(aCallback, aSheet, aLine, aCol);
|
||||
}, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -273,6 +273,7 @@ CssHtmlTree.prototype = {
|
|||
this._matchedProperties = null;
|
||||
|
||||
if (this.htmlComplete) {
|
||||
this.refreshSourceFilter();
|
||||
this.refreshPanel();
|
||||
} else {
|
||||
if (this._refreshProcess) {
|
||||
|
@ -281,6 +282,9 @@ CssHtmlTree.prototype = {
|
|||
|
||||
CssHtmlTree.processTemplate(this.templateRoot, this.root, this);
|
||||
|
||||
// Refresh source filter ... this must be done after templateRoot has been
|
||||
// processed.
|
||||
this.refreshSourceFilter();
|
||||
this.numVisibleProperties = 0;
|
||||
let fragment = this.doc.createDocumentFragment();
|
||||
this._refreshProcess = new UpdateProcess(this.win, CssHtmlTree.propertyNames, {
|
||||
|
@ -362,21 +366,28 @@ CssHtmlTree.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* The change event handler for the onlyUserStyles checkbox. When
|
||||
* onlyUserStyles.checked is true we do not display properties that have no
|
||||
* matched selectors, and we do not display UA styles. If .checked is false we
|
||||
* do display even properties with no matched selectors, and we include the UA
|
||||
* styles.
|
||||
* The change event handler for the onlyUserStyles checkbox.
|
||||
*
|
||||
* @param {Event} aEvent the DOM Event object.
|
||||
*/
|
||||
onlyUserStylesChanged: function CssHtmltree_onlyUserStylesChanged(aEvent)
|
||||
{
|
||||
this.refreshSourceFilter();
|
||||
this.refreshPanel();
|
||||
},
|
||||
|
||||
/**
|
||||
* When onlyUserStyles.checked is true we only display properties that have
|
||||
* matched selectors and have been included by the document or one of the
|
||||
* document's stylesheets. If .checked is false we display all properties
|
||||
* including those that come from UA stylesheets.
|
||||
*/
|
||||
refreshSourceFilter: function CssHtmlTree_setSourceFilter()
|
||||
{
|
||||
this._matchedProperties = null;
|
||||
this.cssLogic.sourceFilter = this.showOnlyUserStyles ?
|
||||
CssLogic.FILTER.ALL :
|
||||
CssLogic.FILTER.UA;
|
||||
this.refreshPanel();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -974,4 +985,24 @@ SelectorView.prototype = {
|
|||
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* When a css link is clicked this method is called in order to either:
|
||||
* 1. Open the link in view source (for element style attributes).
|
||||
* 2. Open the link in the style editor.
|
||||
*
|
||||
* @param aEvent The click event
|
||||
*/
|
||||
openStyleEditor: function(aEvent)
|
||||
{
|
||||
if (this.selectorInfo.selector._cssRule._cssSheet) {
|
||||
let styleSheet = this.selectorInfo.selector._cssRule._cssSheet.domSheet;
|
||||
let line = this.selectorInfo.ruleLine;
|
||||
|
||||
this.tree.win.StyleEditor.openChrome(styleSheet, line);
|
||||
} else {
|
||||
let href = this.selectorInfo.sourceElement.ownerDocument.location.href;
|
||||
this.tree.win.openUILinkIn("view-source:" + href, "window");
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -232,7 +232,7 @@ CssLogic.prototype = {
|
|||
// Update the CssSheet objects.
|
||||
this.forEachSheet(function(aSheet) {
|
||||
aSheet._sheetAllowed = -1;
|
||||
if (!aSheet.systemSheet && aSheet.sheetAllowed) {
|
||||
if (aSheet.contentSheet && aSheet.sheetAllowed) {
|
||||
ruleCount += aSheet.ruleCount;
|
||||
}
|
||||
}, this);
|
||||
|
@ -345,7 +345,7 @@ CssLogic.prototype = {
|
|||
|
||||
let sheets = [];
|
||||
this.forEachSheet(function (aSheet) {
|
||||
if (!aSheet.systemSheet) {
|
||||
if (aSheet.contentSheet) {
|
||||
sheets.push(aSheet);
|
||||
}
|
||||
}, this);
|
||||
|
@ -395,7 +395,7 @@ CssLogic.prototype = {
|
|||
}
|
||||
|
||||
sheet = new CssSheet(this, aDomSheet, aIndex);
|
||||
if (sheet.sheetAllowed && !sheet.systemSheet) {
|
||||
if (sheet.sheetAllowed && sheet.contentSheet) {
|
||||
this._ruleCount += sheet.ruleCount;
|
||||
}
|
||||
|
||||
|
@ -569,7 +569,7 @@ CssLogic.prototype = {
|
|||
|
||||
this.forEachSheet(function (aSheet) {
|
||||
// We do not show unmatched selectors from system stylesheets
|
||||
if (aSheet.systemSheet || aSheet.disabled || !aSheet.mediaMatches) {
|
||||
if (!aSheet.contentSheet || aSheet.disabled || !aSheet.mediaMatches) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -664,7 +664,7 @@ CssLogic.prototype = {
|
|||
sheet._passId = this._passId;
|
||||
}
|
||||
|
||||
if (filter !== CssLogic.FILTER.UA && sheet.systemSheet) {
|
||||
if (filter === CssLogic.FILTER.ALL && !sheet.contentSheet) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -710,7 +710,7 @@ CssLogic.prototype = {
|
|||
let result = {};
|
||||
|
||||
this.forSomeSheets(function (aSheet) {
|
||||
if (aSheet.systemSheet || aSheet.disabled || !aSheet.mediaMatches) {
|
||||
if (!aSheet.contentSheet || aSheet.disabled || !aSheet.mediaMatches) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -865,29 +865,23 @@ XPCOMUtils.defineLazyGetter(CssLogic, "_strings", function() Services.strings
|
|||
.createBundle("chrome://browser/locale/devtools/styleinspector.properties"));
|
||||
|
||||
/**
|
||||
* Is the given property sheet a system (user agent) stylesheet?
|
||||
* Is the given property sheet a content stylesheet?
|
||||
*
|
||||
* @param {CSSStyleSheet} aSheet a stylesheet
|
||||
* @return {boolean} true if the given stylesheet is a system stylesheet or
|
||||
* @return {boolean} true if the given stylesheet is a content stylesheet,
|
||||
* false otherwise.
|
||||
*/
|
||||
CssLogic.isSystemStyleSheet = function CssLogic_isSystemStyleSheet(aSheet)
|
||||
CssLogic.isContentStylesheet = function CssLogic_isContentStylesheet(aSheet)
|
||||
{
|
||||
if (!aSheet) {
|
||||
// All sheets with owner nodes have been included by content.
|
||||
if (aSheet.ownerNode) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let url = aSheet.href;
|
||||
|
||||
if (!url) return false;
|
||||
if (url.length === 0) return true;
|
||||
|
||||
// Check for http[s]
|
||||
if (url[0] === 'h') return false;
|
||||
if (url.substr(0, 9) === "resource:") return true;
|
||||
if (url.substr(0, 7) === "chrome:") return true;
|
||||
if (url === "XPCSafeJSObjectWrapper.cpp") return true;
|
||||
if (url.substr(0, 6) === "about:") return true;
|
||||
// If the sheet has a CSSImportRule we need to check the parent stylesheet.
|
||||
if (aSheet.ownerRule instanceof Ci.nsIDOMCSSImportRule) {
|
||||
return CssLogic.isContentStylesheet(aSheet.parentStyleSheet);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
@ -942,7 +936,7 @@ function CssSheet(aCssLogic, aDomSheet, aIndex)
|
|||
{
|
||||
this._cssLogic = aCssLogic;
|
||||
this.domSheet = aDomSheet;
|
||||
this.index = this.systemSheet ? -100 * aIndex : aIndex;
|
||||
this.index = this.contentSheet ? aIndex : -100 * aIndex;
|
||||
|
||||
// Cache of the sheets href. Cached by the getter.
|
||||
this._href = null;
|
||||
|
@ -960,21 +954,21 @@ function CssSheet(aCssLogic, aDomSheet, aIndex)
|
|||
|
||||
CssSheet.prototype = {
|
||||
_passId: null,
|
||||
_systemSheet: null,
|
||||
_contentSheet: null,
|
||||
_mediaMatches: null,
|
||||
|
||||
/**
|
||||
* Tells if the stylesheet is provided by the browser or not.
|
||||
*
|
||||
* @return {boolean} true if this is a browser-provided stylesheet, or false
|
||||
* @return {boolean} false if this is a browser-provided stylesheet, or true
|
||||
* otherwise.
|
||||
*/
|
||||
get systemSheet()
|
||||
get contentSheet()
|
||||
{
|
||||
if (this._systemSheet === null) {
|
||||
this._systemSheet = CssLogic.isSystemStyleSheet(this.domSheet);
|
||||
if (this._contentSheet === null) {
|
||||
this._contentSheet = CssLogic.isContentStylesheet(this.domSheet);
|
||||
}
|
||||
return this._systemSheet;
|
||||
return this._contentSheet;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1048,7 +1042,7 @@ CssSheet.prototype = {
|
|||
this._sheetAllowed = true;
|
||||
|
||||
let filter = this._cssLogic.sourceFilter;
|
||||
if (filter === CssLogic.FILTER.ALL && this.systemSheet) {
|
||||
if (filter === CssLogic.FILTER.ALL && !this.contentSheet) {
|
||||
this._sheetAllowed = false;
|
||||
}
|
||||
if (filter !== CssLogic.FILTER.ALL && filter !== CssLogic.FILTER.UA) {
|
||||
|
@ -1202,13 +1196,13 @@ function CssRule(aCssSheet, aDomRule, aElement)
|
|||
this.line = this._cssSheet._cssLogic.domUtils.getRuleLine(this._domRule);
|
||||
this.source = this._cssSheet.shortSource + ":" + this.line;
|
||||
this.href = this._cssSheet.href;
|
||||
this.systemRule = this._cssSheet.systemSheet;
|
||||
this.contentRule = this._cssSheet.contentSheet;
|
||||
} else if (aElement) {
|
||||
this._selectors = [ new CssSelector(this, "@element.style") ];
|
||||
this.line = -1;
|
||||
this.source = CssLogic.l10n("rule.sourceElement");
|
||||
this.href = "#";
|
||||
this.systemRule = false;
|
||||
this.contentRule = true;
|
||||
this.sourceElement = aElement;
|
||||
}
|
||||
}
|
||||
|
@ -1396,12 +1390,12 @@ CssSelector.prototype = {
|
|||
/**
|
||||
* Check if the selector comes from a browser-provided stylesheet.
|
||||
*
|
||||
* @return {boolean} true if the selector comes from a browser-provided
|
||||
* @return {boolean} true if the selector comes from a content-provided
|
||||
* stylesheet, or false otherwise.
|
||||
*/
|
||||
get systemRule()
|
||||
get contentRule()
|
||||
{
|
||||
return this._cssRule.systemRule;
|
||||
return this._cssRule.contentRule;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1794,12 +1788,12 @@ function CssSelectorInfo(aSelector, aProperty, aValue, aStatus)
|
|||
4 important
|
||||
5 inline important
|
||||
*/
|
||||
let scorePrefix = this.systemRule ? 0 : 2;
|
||||
let scorePrefix = this.contentRule ? 2 : 0;
|
||||
if (this.elementStyle) {
|
||||
scorePrefix++;
|
||||
}
|
||||
if (this.important) {
|
||||
scorePrefix += this.systemRule ? 1 : 2;
|
||||
scorePrefix += this.contentRule ? 2 : 1;
|
||||
}
|
||||
|
||||
this.specificityScore = "" + scorePrefix + this.specificity.ids +
|
||||
|
@ -1902,9 +1896,9 @@ CssSelectorInfo.prototype = {
|
|||
* @return {boolean} true if the selector comes from a browser-provided
|
||||
* stylesheet, or false otherwise.
|
||||
*/
|
||||
get systemRule()
|
||||
get contentRule()
|
||||
{
|
||||
return this.selector.systemRule;
|
||||
return this.selector.contentRule;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1916,8 +1910,8 @@ CssSelectorInfo.prototype = {
|
|||
*/
|
||||
compareTo: function CssSelectorInfo_compareTo(aThat)
|
||||
{
|
||||
if (this.systemRule && !aThat.systemRule) return 1;
|
||||
if (!this.systemRule && aThat.systemRule) return -1;
|
||||
if (!this.contentRule && aThat.contentRule) return 1;
|
||||
if (this.contentRule && !aThat.contentRule) return -1;
|
||||
|
||||
if (this.elementStyle && !aThat.elementStyle) {
|
||||
if (!this.important && aThat.important) return 1;
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
"use strict"
|
||||
"use strict";
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
@ -181,8 +181,8 @@ ElementStyle.prototype = {
|
|||
let domRule = domRules.GetElementAt(i);
|
||||
|
||||
// XXX: Optionally provide access to system sheets.
|
||||
let systemSheet = CssLogic.isSystemStyleSheet(domRule.parentStyleSheet);
|
||||
if (systemSheet) {
|
||||
let contentSheet = CssLogic.isContentStylesheet(domRule.parentStyleSheet);
|
||||
if (!contentSheet) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -324,7 +324,7 @@ ElementStyle.prototype = {
|
|||
aProp.overridden = overridden;
|
||||
return dirty;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A single style rule or declaration.
|
||||
|
@ -358,11 +358,9 @@ Rule.prototype = {
|
|||
if (this._title) {
|
||||
return this._title;
|
||||
}
|
||||
let sheet = this.domRule ? this.domRule.parentStyleSheet : null;
|
||||
this._title = CssLogic.shortSource(sheet);
|
||||
this._title = CssLogic.shortSource(this.sheet);
|
||||
if (this.domRule) {
|
||||
let line = this.elementStyle.domUtils.getRuleLine(this.domRule);
|
||||
this._title += ":" + line;
|
||||
this._title += ":" + this.ruleLine;
|
||||
}
|
||||
|
||||
if (this.inherited) {
|
||||
|
@ -378,6 +376,26 @@ Rule.prototype = {
|
|||
return this._title;
|
||||
},
|
||||
|
||||
/**
|
||||
* The rule's stylesheet.
|
||||
*/
|
||||
get sheet()
|
||||
{
|
||||
return this.domRule ? this.domRule.parentStyleSheet : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* The rule's line within a stylesheet
|
||||
*/
|
||||
get ruleLine()
|
||||
{
|
||||
if (!this.sheet) {
|
||||
// No stylesheet, no ruleLine
|
||||
return null;
|
||||
}
|
||||
return this.elementStyle.domUtils.getRuleLine(this.domRule);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new TextProperty to include in the rule.
|
||||
*
|
||||
|
@ -530,7 +548,7 @@ Rule.prototype = {
|
|||
this.textProps.push(textProp);
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A single property in a rule's cssText.
|
||||
|
@ -618,7 +636,7 @@ TextProperty.prototype = {
|
|||
{
|
||||
this.rule.removeProperty(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
@ -643,7 +661,7 @@ TextProperty.prototype = {
|
|||
* apply to a given element. After construction, the 'element'
|
||||
* property will be available with the user interface.
|
||||
*
|
||||
* @param Document aDocument
|
||||
* @param Document aDoc
|
||||
* The document that will contain the rule view.
|
||||
* @param object aStore
|
||||
* The CSS rule view can use this object to store metadata
|
||||
|
@ -655,7 +673,6 @@ function CssRuleView(aDoc, aStore)
|
|||
{
|
||||
this.doc = aDoc;
|
||||
this.store = aStore;
|
||||
|
||||
this.element = this.doc.createElementNS(XUL_NS, "vbox");
|
||||
this.element.setAttribute("tabindex", "0");
|
||||
this.element.classList.add("ruleview");
|
||||
|
@ -768,6 +785,14 @@ RuleEditor.prototype = {
|
|||
class: "ruleview-rule-source",
|
||||
textContent: this.rule.title
|
||||
});
|
||||
source.addEventListener("click", function() {
|
||||
let rule = this.rule;
|
||||
let evt = this.doc.createEvent("CustomEvent");
|
||||
evt.initCustomEvent("CssRuleViewCSSLinkClicked", true, false, {
|
||||
rule: rule,
|
||||
});
|
||||
this.element.dispatchEvent(evt);
|
||||
}.bind(this));
|
||||
|
||||
let code = createChild(this.element, "div", {
|
||||
class: "ruleview-code"
|
||||
|
@ -1094,8 +1119,6 @@ TextPropertyEditor.prototype = {
|
|||
_parseValue: function TextPropertyEditor_parseValue(aValue)
|
||||
{
|
||||
let pieces = aValue.split("!", 2);
|
||||
let value = pieces[0];
|
||||
let priority = pieces.length > 1 ? pieces[1] : "";
|
||||
return {
|
||||
value: pieces[0].trim(),
|
||||
priority: (pieces.length > 1 ? pieces[1].trim() : "")
|
||||
|
|
|
@ -114,7 +114,7 @@ To visually debug the templates without running firefox, alter the display:none
|
|||
${selector.humanReadableText(__element)}
|
||||
</td>
|
||||
<td class="rule-link">
|
||||
<a target="_blank" href="view-source:${selector.selectorInfo.href}" class="link"
|
||||
<a target="_blank" onclick="${selector.openStyleEditor}" class="link"
|
||||
title="${selector.selectorInfo.href}">${selector.selectorInfo.source}</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -59,11 +59,19 @@ _BROWSER_TEST_FILES = \
|
|||
browser_ruleview_manipulation.js \
|
||||
browser_ruleview_override.js \
|
||||
browser_ruleview_ui.js \
|
||||
browser_bug705707_is_content_stylesheet.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
_BROWSER_TEST_PAGES = \
|
||||
browser_bug683672.html \
|
||||
browser_bug705707_is_content_stylesheet.html \
|
||||
browser_bug705707_is_content_stylesheet_imported.css \
|
||||
browser_bug705707_is_content_stylesheet_imported2.css \
|
||||
browser_bug705707_is_content_stylesheet_linked.css \
|
||||
browser_bug705707_is_content_stylesheet_script.css \
|
||||
browser_bug705707_is_content_stylesheet.xul \
|
||||
browser_bug705707_is_content_stylesheet_xul.css \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>test</title>
|
||||
|
||||
<link href="./browser_bug705707_is_content_stylesheet_linked.css" rel="stylesheet" type="text/css">
|
||||
|
||||
<script>
|
||||
// Load script.css
|
||||
function loadCSS() {
|
||||
var link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.type = 'text/css';
|
||||
link.href = "./browser_bug705707_is_content_stylesheet_script.css";
|
||||
document.getElementsByTagName('head')[0].appendChild(link);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
table {
|
||||
border: 1px solid #000;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="loadCSS();">
|
||||
<table id="target">
|
||||
<tr>
|
||||
<td>
|
||||
<h3>Simple test</h3>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,100 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the correct stylesheets origins are identified in HTML & XUL
|
||||
// stylesheets
|
||||
|
||||
let doc;
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/" +
|
||||
"test/browser_bug705707_is_content_stylesheet.html";
|
||||
const TEST_URI2 = "http://example.com/browser/browser/devtools/styleinspector/" +
|
||||
"test/browser_bug705707_is_content_stylesheet.xul";
|
||||
const XUL_URI = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService)
|
||||
.newURI(TEST_URI2, null, null);
|
||||
|
||||
let tempScope = {};
|
||||
Cu.import("resource:///modules/devtools/CssLogic.jsm", tempScope);
|
||||
let CssLogic = tempScope.CssLogic;
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
addTab(TEST_URI);
|
||||
browser.addEventListener("load", htmlLoaded, true);
|
||||
}
|
||||
|
||||
function htmlLoaded()
|
||||
{
|
||||
browser.removeEventListener("load", htmlLoaded, true);
|
||||
doc = content.document;
|
||||
testFromHTML()
|
||||
}
|
||||
|
||||
function testFromHTML()
|
||||
{
|
||||
let target = doc.querySelector("#target");
|
||||
|
||||
executeSoon(function() {
|
||||
checkSheets(target);
|
||||
gBrowser.removeCurrentTab();
|
||||
openXUL();
|
||||
});
|
||||
}
|
||||
|
||||
function openXUL()
|
||||
{
|
||||
Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager)
|
||||
.add(XUL_URI, 'allowXULXBL', Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
addTab(TEST_URI2);
|
||||
browser.addEventListener("load", xulLoaded, true);
|
||||
}
|
||||
|
||||
function xulLoaded()
|
||||
{
|
||||
browser.removeEventListener("load", xulLoaded, true);
|
||||
doc = content.document;
|
||||
testFromXUL()
|
||||
}
|
||||
|
||||
function testFromXUL()
|
||||
{
|
||||
let target = doc.querySelector("#target");
|
||||
|
||||
executeSoon(function() {
|
||||
checkSheets(target);
|
||||
finishUp();
|
||||
});
|
||||
}
|
||||
|
||||
function checkSheets(aTarget)
|
||||
{
|
||||
let domUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(Ci.inIDOMUtils);
|
||||
let domRules = domUtils.getCSSStyleRules(aTarget);
|
||||
|
||||
for (let i = 0, n = domRules.Count(); i < n; i++) {
|
||||
let domRule = domRules.GetElementAt(i);
|
||||
let sheet = domRule.parentStyleSheet;
|
||||
let isContentSheet = CssLogic.isContentStylesheet(sheet);
|
||||
|
||||
if (!sheet.href ||
|
||||
/browser_bug705707_is_content_stylesheet_/.test(sheet.href)) {
|
||||
ok(isContentSheet, sheet.href + " identified as content stylesheet");
|
||||
} else {
|
||||
ok(!isContentSheet, sheet.href + " identified as non-content stylesheet");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
info("finishing up");
|
||||
Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager)
|
||||
.add(XUL_URI, 'allowXULXBL', Ci.nsIPermissionManager.DENY_ACTION);
|
||||
doc = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin/xul.css" type="text/css"?>
|
||||
<?xml-stylesheet href="./browser_bug705707_is_content_stylesheet_xul.css"
|
||||
type="text/css"?>
|
||||
<!DOCTYPE window>
|
||||
<window id="testwindow" xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<label id="target" value="Simple XUL document" />
|
||||
</window>
|
|
@ -0,0 +1,5 @@
|
|||
@import url("./browser_bug705707_is_content_stylesheet_imported2.css");
|
||||
|
||||
#target {
|
||||
text-decoration: underline;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#target {
|
||||
text-decoration: underline;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
@import url("./browser_bug705707_is_content_stylesheet_imported.css");
|
||||
|
||||
table {
|
||||
opacity: 1;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#target {
|
||||
font-size: 200px;
|
||||
}
|
|
@ -126,6 +126,40 @@ gcli.addCommand({
|
|||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 'edit' command
|
||||
*/
|
||||
gcli.addCommand({
|
||||
name: "edit",
|
||||
description: gcli.lookup("editDesc"),
|
||||
manual: gcli.lookup("editManual"),
|
||||
params: [
|
||||
{
|
||||
name: 'resource',
|
||||
type: {
|
||||
name: 'resource',
|
||||
include: 'text/css'
|
||||
},
|
||||
description: gcli.lookup("editResourceDesc")
|
||||
},
|
||||
{
|
||||
name: "line",
|
||||
defaultValue: 1,
|
||||
type: {
|
||||
name: "number",
|
||||
min: 1,
|
||||
step: 10
|
||||
},
|
||||
description: gcli.lookup("editLineToJumpToDesc")
|
||||
}
|
||||
],
|
||||
exec: function(args, context) {
|
||||
let hud = HUDService.getHudReferenceById(context.environment.hudId);
|
||||
let StyleEditor = hud.gcliterm.document.defaultView.StyleEditor;
|
||||
StyleEditor.openChrome(args.resource.element, args.line);
|
||||
}
|
||||
});
|
||||
|
||||
let breakpoints = [];
|
||||
|
||||
/**
|
||||
|
|
|
@ -129,3 +129,23 @@ breakdelRemoved=Breakpoint removed
|
|||
# 'console close' command. This string is designed to be shown in a menu
|
||||
# alongside the command name, which is why it should be as short as possible.
|
||||
consolecloseDesc=Close the console
|
||||
|
||||
# LOCALIZATION NOTE (editDesc) A very short description of the 'edit'
|
||||
# command. See editManual for a fuller description of what it does. This
|
||||
# string is designed to be shown in a menu alongside the command name, which
|
||||
# is why it should be as short as possible.
|
||||
editDesc=Tweak a page resource
|
||||
|
||||
# LOCALIZATION NOTE (editManual) A fuller description of the 'edit' command,
|
||||
# displayed when the user asks for help on what it does.
|
||||
editManual=Edit one of the resources that is part of this page (or maybe any generic web resource?)
|
||||
|
||||
# LOCALIZATION NOTE (editResourceDesc) A very short string to describe the
|
||||
# 'resource' parameter to the 'edit' command, which is displayed in a dialog
|
||||
# when the user is using this command.
|
||||
editResourceDesc=URL to edit
|
||||
|
||||
# LOCALIZATION NOTE (editLineToJumpToDesc) A very short string to describe the
|
||||
# 'line' parameter to the 'edit' command, which is displayed in a dialog
|
||||
# when the user is using this command.
|
||||
editLineToJumpToDesc=Line to jump to
|
||||
|
|
|
@ -68,6 +68,9 @@
|
|||
.helplink:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
.link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.helplink {
|
||||
display: block;
|
||||
|
@ -135,6 +138,7 @@
|
|||
.rule-link {
|
||||
text-align: end;
|
||||
-moz-padding-start: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
|
||||
|
@ -200,7 +204,13 @@
|
|||
|
||||
.ruleview-rule-source {
|
||||
background-color: -moz-dialog;
|
||||
color: #0091ff;
|
||||
padding: 2px 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ruleview-rule-source:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.ruleview-code {
|
||||
|
|
|
@ -68,6 +68,9 @@
|
|||
.helplink:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
.link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.helplink {
|
||||
display: block;
|
||||
|
@ -137,6 +140,7 @@
|
|||
.rule-link {
|
||||
text-align: end;
|
||||
-moz-padding-start: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
|
||||
|
@ -202,7 +206,13 @@
|
|||
|
||||
.ruleview-rule-source {
|
||||
background-color: -moz-dialog;
|
||||
color: #0091ff;
|
||||
padding: 2px 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ruleview-rule-source:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.ruleview-code {
|
||||
|
|
|
@ -67,6 +67,9 @@
|
|||
.helplink:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
.link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.helplink {
|
||||
display: block;
|
||||
|
@ -135,6 +138,7 @@
|
|||
.rule-link {
|
||||
text-align: end;
|
||||
-moz-padding-start: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
|
||||
|
@ -200,7 +204,13 @@
|
|||
|
||||
.ruleview-rule-source {
|
||||
background-color: -moz-dialog;
|
||||
color: #0091ff;
|
||||
padding: 2px 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ruleview-rule-source:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.ruleview-code {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include "android/log.h"
|
||||
#include "cutils/properties.h"
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
@ -12,6 +13,7 @@
|
|||
#include "nsStreamUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsRawStructs.h"
|
||||
#include "prinit.h"
|
||||
|
||||
#define USE_GS2_LIBCAMERA
|
||||
#define CameraHardwareInterface CameraHardwareInterface_SGS2
|
||||
|
@ -48,11 +50,11 @@ using namespace mozilla;
|
|||
|
||||
class CameraHardwareInterface {
|
||||
public:
|
||||
typedef enum {
|
||||
enum Type {
|
||||
CAMERA_SGS2,
|
||||
CAMERA_MAGURO,
|
||||
CAMERA_DEFAULT
|
||||
} Type;
|
||||
};
|
||||
|
||||
static Type getType() {
|
||||
char propValue[PROPERTY_VALUE_MAX];
|
||||
|
@ -60,7 +62,7 @@ class CameraHardwareInterface {
|
|||
if (!strcmp(propValue, "GT-I9100"))
|
||||
return CAMERA_SGS2;
|
||||
|
||||
if (!strcmp(propValue, "MSM7627A_SKU1") || !strcmp(propValue, "MSM7627A_SKU3"))
|
||||
if (!strcmp(propValue, "msm7627a_sku1") || !strcmp(propValue, "MSM7627A_SKU3"))
|
||||
return CAMERA_MAGURO;
|
||||
|
||||
printf_stderr("CameraHardwareInterface : unsupported camera for device %s\n", propValue);
|
||||
|
@ -89,30 +91,25 @@ class CameraHardwareInterface {
|
|||
CameraHardwareInterface(PRUint32 aCamera = 0) { };
|
||||
};
|
||||
|
||||
class DlopenWrapper {
|
||||
public:
|
||||
DlopenWrapper() : mHandle(nsnull) { };
|
||||
// Intentionally not trying to dlclose() this handle. That's playing
|
||||
// Russian roulette with security bugs.
|
||||
static void* sCameraLib;
|
||||
static PRCallOnceType sInitCameraLib;
|
||||
|
||||
DlopenWrapper(const char* aLibrary) : mHandle(nsnull) {
|
||||
mHandle = dlopen(aLibrary, RTLD_LAZY);
|
||||
};
|
||||
static PRStatus
|
||||
InitCameraLib()
|
||||
{
|
||||
sCameraLib = dlopen("/system/lib/libcamera.so", RTLD_LAZY);
|
||||
// We might fail to open the camera lib. That's OK.
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
~DlopenWrapper() {
|
||||
if (mHandle)
|
||||
dlclose(mHandle);
|
||||
};
|
||||
|
||||
bool opened() {
|
||||
return mHandle != nsnull;
|
||||
};
|
||||
|
||||
void* dlsym(const char* aFunction) {
|
||||
return ::dlsym(mHandle, aFunction);
|
||||
};
|
||||
|
||||
protected:
|
||||
void* mHandle;
|
||||
};
|
||||
static void*
|
||||
GetCameraLibHandle()
|
||||
{
|
||||
PR_CallOnce(&sInitCameraLib, InitCameraLib);
|
||||
return sCameraLib;
|
||||
}
|
||||
|
||||
template<class T> class CameraImpl : public CameraHardwareInterface {
|
||||
public:
|
||||
|
@ -121,14 +118,13 @@ template<class T> class CameraImpl : public CameraHardwareInterface {
|
|||
typedef sp<T> (*HAL_openCameraHardware_MAGURO)(int, int);
|
||||
|
||||
CameraImpl(PRUint32 aCamera = 0) : mOk(false), mCamera(nsnull) {
|
||||
DlopenWrapper wrapper("/system/lib/libcamera.so");
|
||||
|
||||
if (!wrapper.opened())
|
||||
void* cameraLib = GetCameraLibHandle();
|
||||
if (!cameraLib) {
|
||||
printf_stderr("CameraImpl: Failed to dlopen() camera library.");
|
||||
return;
|
||||
}
|
||||
|
||||
mOk = true;
|
||||
|
||||
void *hal = wrapper.dlsym("HAL_openCameraHardware");
|
||||
void *hal = dlsym(cameraLib, "HAL_openCameraHardware");
|
||||
HAL_openCameraHardware_DEFAULT funct0;
|
||||
HAL_openCameraHardware_SGS2 funct1;
|
||||
HAL_openCameraHardware_MAGURO funct2;
|
||||
|
@ -146,6 +142,11 @@ template<class T> class CameraImpl : public CameraHardwareInterface {
|
|||
mCamera = funct0(aCamera);
|
||||
break;
|
||||
}
|
||||
|
||||
mOk = mCamera != nsnull;
|
||||
if (!mOk) {
|
||||
printf_stderr("CameraImpl: HAL_openCameraHardware() returned NULL (no camera interface).");
|
||||
}
|
||||
}
|
||||
|
||||
bool ok() {
|
||||
|
@ -251,12 +252,11 @@ GonkCameraInputStream::DataCallback(int32_t aMsgType, const sp<IMemory>& aDataPt
|
|||
PRUint32
|
||||
GonkCameraInputStream::getNumberOfCameras() {
|
||||
typedef int (*HAL_getNumberOfCamerasFunct)(void);
|
||||
DlopenWrapper wrapper("/system/lib/libcamera.so");
|
||||
|
||||
if (!wrapper.opened())
|
||||
void* cameraLib = GetCameraLibHandle();
|
||||
if (!cameraLib)
|
||||
return 0;
|
||||
|
||||
void *hal = wrapper.dlsym("HAL_getNumberOfCameras");
|
||||
void *hal = dlsym(cameraLib, "HAL_getNumberOfCameras");
|
||||
if (nsnull == hal)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -120,6 +120,10 @@ ThreadActor.prototype = {
|
|||
},
|
||||
|
||||
disconnect: function TA_disconnect() {
|
||||
if (this._state == "paused") {
|
||||
this.onResume();
|
||||
}
|
||||
|
||||
this._state = "exited";
|
||||
if (this.dbg) {
|
||||
this.dbg.enabled = false;
|
||||
|
|
Загрузка…
Ссылка в новой задаче