зеркало из https://github.com/mozilla/gecko-dev.git
merge mozilla-central to mozilla-inbound
This commit is contained in:
Коммит
807da10e4e
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"revision": "3a5bfe8c6e0738750ff4e674a2235fee90cc0ba4",
|
||||
"revision": "a6b81f7d4b84287a2bdf0ce78df08fed9fd46bee",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -546,14 +546,14 @@ var FullZoom = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Asynchronously broadcasts a "browser-fullZoom:locationChange" notification
|
||||
* so that tests can select tabs, load pages, etc. and be notified when the
|
||||
* zoom levels on those pages change. The notification is always asynchronous
|
||||
* so that observers are guaranteed a consistent behavior.
|
||||
* Asynchronously broadcasts "FullZoom:TESTS:location-change" so that tests
|
||||
* can select tabs, load pages, etc. and be notified when the zoom levels on
|
||||
* those pages change. The notification is always asynchronous so that
|
||||
* observers are guaranteed a consistent behavior.
|
||||
*/
|
||||
_notifyOnLocationChange: function FullZoom__notifyOnLocationChange() {
|
||||
this._executeSoon(function () {
|
||||
Services.obs.notifyObservers(null, "browser-fullZoom:locationChange", "");
|
||||
Services.obs.notifyObservers(null, "FullZoom:TESTS:location-change", "");
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -300,10 +300,10 @@ let FullZoomHelper = {
|
|||
}
|
||||
if (tab)
|
||||
gBrowser.selectedTab = tab;
|
||||
Services.obs.addObserver(function obs() {
|
||||
Services.obs.removeObserver(obs, "browser-fullZoom:locationChange");
|
||||
Services.obs.addObserver(function obs(subj, topic, data) {
|
||||
Services.obs.removeObserver(obs, topic);
|
||||
deferred.resolve();
|
||||
}, "browser-fullZoom:locationChange", false);
|
||||
}, "FullZoom:TESTS:location-change", false);
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
|
|
|
@ -509,7 +509,9 @@ BrowserGlue.prototype = {
|
|||
samples = Services.prefs.getIntPref("browser.slowStartup.samples");
|
||||
} catch (e) { }
|
||||
|
||||
averageTime = (averageTime * samples + currentTime) / ++samples;
|
||||
let totalTime = (averageTime * samples) + currentTime;
|
||||
samples++;
|
||||
averageTime = totalTime / samples;
|
||||
|
||||
if (samples >= Services.prefs.getIntPref("browser.slowStartup.maxSamples")) {
|
||||
if (averageTime > Services.prefs.getIntPref("browser.slowStartup.timeThreshold"))
|
||||
|
|
|
@ -14,7 +14,7 @@ function test() {
|
|||
function doTestWhenReady(aIsZoomedWindow, aWindow, aCallback) {
|
||||
// Need to wait on two things, the ordering of which is not guaranteed:
|
||||
// (1) the page load, and (2) FullZoom's update to the new page's zoom
|
||||
// level. FullZoom broadcasts "browser-fullZoom:locationChange" when its
|
||||
// level. FullZoom broadcasts "FullZoom:TESTS:location-change" when its
|
||||
// update is done. (See bug 856366 for details.)
|
||||
|
||||
let n = 0;
|
||||
|
@ -26,12 +26,11 @@ function test() {
|
|||
doTest(aIsZoomedWindow, aWindow, aCallback);
|
||||
}, true);
|
||||
|
||||
let topic = "browser-fullZoom:locationChange";
|
||||
Services.obs.addObserver(function onLocationChange() {
|
||||
Services.obs.addObserver(function onLocationChange(subj, topic, data) {
|
||||
Services.obs.removeObserver(onLocationChange, topic);
|
||||
if (++n == 2)
|
||||
doTest(aIsZoomedWindow, aWindow, aCallback);
|
||||
}, topic, false);
|
||||
}, "FullZoom:TESTS:location-change", false);
|
||||
|
||||
browser.loadURI("about:blank");
|
||||
}
|
||||
|
|
|
@ -465,6 +465,11 @@ gcli.addCommand({
|
|||
type: "string",
|
||||
description: lookup("GlobDesc"),
|
||||
defaultValue: null
|
||||
},
|
||||
{
|
||||
name: "invert",
|
||||
type: "boolean",
|
||||
description: lookup("InvertDesc")
|
||||
}
|
||||
],
|
||||
returnType: "dom",
|
||||
|
@ -484,8 +489,9 @@ gcli.addCommand({
|
|||
// Filter the sources down to those that we will need to black box.
|
||||
|
||||
function shouldBlackBox(source) {
|
||||
return globRegExp && globRegExp.test(source.url)
|
||||
var value = globRegExp && globRegExp.test(source.url)
|
||||
|| args.source && source.url == args.source;
|
||||
return args.invert ? !value : value;
|
||||
}
|
||||
|
||||
const toBlackBox = [s.attachment.source
|
||||
|
|
|
@ -56,6 +56,8 @@ function test() {
|
|||
.then(testUnBlackBoxSource)
|
||||
.then(testBlackBoxGlob)
|
||||
.then(testUnBlackBoxGlob)
|
||||
.then(testBlackBoxInvert)
|
||||
.then(testUnBlackBoxInvert)
|
||||
.then(null, function (error) {
|
||||
ok(false, "Got an error: " + error.message + "\n" + error.stack);
|
||||
})
|
||||
|
@ -124,6 +126,36 @@ function testUnBlackBoxGlob() {
|
|||
});
|
||||
}
|
||||
|
||||
function testBlackBoxInvert() {
|
||||
return cmd("dbg blackbox --invert --glob *blackboxing_t*.js", 3,
|
||||
[/blackboxing_three\.js/g, /blackboxing_two\.js/g])
|
||||
.then(function () {
|
||||
ok(!getBlackBoxCheckbox(BLACKBOXME_URL).checked,
|
||||
"blackboxme should be black boxed because it doesn't match the glob");
|
||||
ok(!getBlackBoxCheckbox(BLACKBOXONE_URL).checked,
|
||||
"blackbox_one should be black boxed because it doesn't match the glob");
|
||||
ok(!getBlackBoxCheckbox(TEST_URL).checked,
|
||||
"TEST_URL should be black boxed because it doesn't match the glob");
|
||||
|
||||
ok(getBlackBoxCheckbox(BLACKBOXTWO_URL).checked,
|
||||
"blackbox_two should not be black boxed because it matches the glob");
|
||||
ok(getBlackBoxCheckbox(BLACKBOXTHREE_URL).checked,
|
||||
"blackbox_three should not be black boxed because it matches the glob");
|
||||
});
|
||||
}
|
||||
|
||||
function testUnBlackBoxInvert() {
|
||||
return cmd("dbg unblackbox --invert --glob *blackboxing_t*.js", 3)
|
||||
.then(function () {
|
||||
ok(getBlackBoxCheckbox(BLACKBOXME_URL).checked,
|
||||
"blackboxme should be un-black boxed because it does not match the glob");
|
||||
ok(getBlackBoxCheckbox(BLACKBOXONE_URL).checked,
|
||||
"blackbox_one should be un-black boxed because it does not match the glob");
|
||||
ok(getBlackBoxCheckbox(TEST_URL).checked,
|
||||
"TEST_URL should be un-black boxed because it doesn't match the glob");
|
||||
});
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
gTarget = null;
|
||||
gPanel = null;
|
||||
|
|
|
@ -12,7 +12,7 @@ let Services = tempScope.Services;
|
|||
// Disable logging for faster test runs. Set this pref to true if you want to
|
||||
// debug a test in your try runs.
|
||||
let gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", false);
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", true);
|
||||
|
||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm", tempScope);
|
||||
Cu.import("resource://gre/modules/devtools/dbg-client.jsm", tempScope);
|
||||
|
|
|
@ -398,6 +398,13 @@ function parseRawProfile(requestID, params, rawProfile) {
|
|||
});
|
||||
}
|
||||
|
||||
if (protocol.startsWith("file")) {
|
||||
return ensureResource("file_" + host, {
|
||||
type: "file",
|
||||
name: host
|
||||
});
|
||||
}
|
||||
|
||||
return ensureResource("otherhost_" + host, {
|
||||
type: "otherhost",
|
||||
name: host
|
||||
|
|
|
@ -50,6 +50,6 @@ function runTests() {
|
|||
assertSampleAndFinish();
|
||||
});
|
||||
|
||||
let profile = gPanel.profiles.get(2);
|
||||
let profile = gPanel.profiles.get(1);
|
||||
gPanel.sidebar.selectedItem = gPanel.sidebar.getItemByProfile(profile);
|
||||
}
|
|
@ -60,7 +60,7 @@ function test() {
|
|||
let file = FileUtils.getFile("TmpD", ["tmpprofile.json"]);
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8));
|
||||
|
||||
gPanel.saveProfile(file, gData).then(() => {dump("\n\nsup\n\n");}, () => {dump("\n\n:(((\n\n")})
|
||||
gPanel.saveProfile(file, gData)
|
||||
.then(gPanel.loadProfile.bind(gPanel, file))
|
||||
.then(checkData);
|
||||
});
|
||||
|
|
|
@ -582,7 +582,6 @@ function SideMenuItem(aGroup, aContents, aTooltip, aArrowFlag, aCheckboxFlag, aA
|
|||
let container = this._container = this.document.createElement("hbox");
|
||||
container.className = "side-menu-widget-item";
|
||||
container.setAttribute("tooltiptext", aTooltip);
|
||||
container.setAttribute("align", "start");
|
||||
|
||||
let target = this._target = this.document.createElement("vbox");
|
||||
target.className = "side-menu-widget-item-contents";
|
||||
|
@ -590,6 +589,7 @@ function SideMenuItem(aGroup, aContents, aTooltip, aArrowFlag, aCheckboxFlag, aA
|
|||
// Show a checkbox before the content.
|
||||
if (aCheckboxFlag) {
|
||||
let checkbox = this._checkbox = this._makeCheckbox(aAttachment);
|
||||
checkbox.setAttribute("align", "start");
|
||||
container.appendChild(checkbox);
|
||||
}
|
||||
|
||||
|
|
|
@ -379,7 +379,7 @@ CssHtmlTree.prototype = {
|
|||
this._matchedProperties = null;
|
||||
this.cssLogic.sourceFilter = this.includeBrowserStyles ?
|
||||
CssLogic.FILTER.UA :
|
||||
CssLogic.FILTER.ALL;
|
||||
CssLogic.FILTER.USER;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -901,7 +901,7 @@ SelectorView.prototype = {
|
|||
{
|
||||
let inspector = this.tree.styleInspector.inspector;
|
||||
let contentDoc = inspector.selection.document;
|
||||
let cssSheet = this.selectorInfo.selector._cssRule._cssSheet;
|
||||
let cssSheet = this.selectorInfo.selector.cssRule._cssSheet;
|
||||
let line = this.selectorInfo.ruleLine || 0;
|
||||
let contentSheet = false;
|
||||
let styleSheet;
|
||||
|
@ -950,4 +950,4 @@ SelectorView.prototype = {
|
|||
};
|
||||
|
||||
exports.CssHtmlTree = CssHtmlTree;
|
||||
exports.PropertyView = PropertyView;
|
||||
exports.PropertyView = PropertyView;
|
||||
|
|
|
@ -28,7 +28,7 @@ function runTests(doc) {
|
|||
let selectorText = selectors[i];
|
||||
let selector = new CssSelector(cssRule, selectorText, i);
|
||||
let expected = getExpectedSpecificity(selectorText);
|
||||
let specificity = DOMUtils.getSpecificity(selector._cssRule,
|
||||
let specificity = DOMUtils.getSpecificity(selector.cssRule,
|
||||
selector.selectorIndex)
|
||||
is(specificity, expected,
|
||||
'selector "' + selectorText + '" has a specificity of ' + expected);
|
||||
|
|
|
@ -427,6 +427,10 @@ dbgBlackBoxSourceDesc=A specific source to black box
|
|||
# 'glob' parameter to the 'dbg blackbox' command.
|
||||
dbgBlackBoxGlobDesc=Black box all sources that match this glob (for example: "*.min.js")
|
||||
|
||||
# LOCALIZATION NOTE (dbgBlackBoxInvertDesc) A very short string used to describe the
|
||||
# 'invert' parameter to the 'dbg blackbox' command.
|
||||
dbgBlackBoxInvertDesc=Invert matching, so that we black box every source that is not the source provided or does not match the provided glob pattern.
|
||||
|
||||
# LOCALIZATION NOTE (dbgBlackBoxEmptyDesc) A very short string used to let the
|
||||
# user know that no sources were black boxed.
|
||||
dbgBlackBoxEmptyDesc=(No sources black boxed)
|
||||
|
@ -465,6 +469,10 @@ dbgUnBlackBoxNonEmptyDesc=Stopped black boxing the following sources:
|
|||
# text).
|
||||
dbgUnBlackBoxErrorDesc=Error stopping black boxing:
|
||||
|
||||
# LOCALIZATION NOTE (dbgUnBlackBoxInvertDesc) A very short string used to describe the
|
||||
# 'invert' parameter to the 'dbg unblackbox' command.
|
||||
dbgUnBlackBoxInvertDesc=Invert matching, so that we stop black boxing every source that is not the source provided or does not match the provided glob pattern.
|
||||
|
||||
# LOCALIZATION NOTE (consolecloseDesc) A very short description of the
|
||||
# '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.
|
||||
|
|
|
@ -471,7 +471,8 @@
|
|||
]]>
|
||||
</handler>
|
||||
|
||||
<handler event="keypress" phase="capturing" keycode="VK_RETURN">
|
||||
<handler event="keypress" phase="capturing" keycode="VK_RETURN"
|
||||
modifiers="accel shift any">
|
||||
<![CDATA[
|
||||
if (this.popup.submitSelected())
|
||||
return;
|
||||
|
|
|
@ -154,6 +154,51 @@ gTests.push({
|
|||
}
|
||||
});
|
||||
|
||||
gTests.push({
|
||||
desc: "Control-Enter in urlbar",
|
||||
setUp: setUp,
|
||||
tearDown: tearDown,
|
||||
run: function () {
|
||||
sendElementTap(window, gEdit);
|
||||
ok(gEdit.isEditing, "focus urlbar: in editing mode");
|
||||
|
||||
EventUtils.sendString("example", window);
|
||||
EventUtils.synthesizeKey("VK_RETURN", { accelKey: true }, window);
|
||||
is(gEdit.value, "www.example.com", "Control-enter adds www. and .com");
|
||||
ok(!gEdit.isEditing, "hit enter in urlbar: not in editing mode");
|
||||
}
|
||||
});
|
||||
|
||||
gTests.push({
|
||||
desc: "Shift-Enter in urlbar",
|
||||
setUp: setUp,
|
||||
tearDown: tearDown,
|
||||
run: function () {
|
||||
sendElementTap(window, gEdit);
|
||||
ok(gEdit.isEditing, "focus urlbar: in editing mode");
|
||||
|
||||
EventUtils.sendString("example", window);
|
||||
EventUtils.synthesizeKey("VK_RETURN", { shiftKey: true }, window);
|
||||
is(gEdit.value, "www.example.net", "Shift-enter adds www. and .net");
|
||||
ok(!gEdit.isEditing, "hit enter in urlbar: not in editing mode");
|
||||
}
|
||||
});
|
||||
|
||||
gTests.push({
|
||||
desc: "Control-Shift-Enter in urlbar",
|
||||
setUp: setUp,
|
||||
tearDown: tearDown,
|
||||
run: function () {
|
||||
sendElementTap(window, gEdit);
|
||||
ok(gEdit.isEditing, "focus urlbar: in editing mode");
|
||||
|
||||
EventUtils.sendString("example", window);
|
||||
EventUtils.synthesizeKey("VK_RETURN", { accelKey: true, shiftKey: true }, window);
|
||||
is(gEdit.value, "www.example.org", "Shift-enter adds www. and .org");
|
||||
ok(!gEdit.isEditing, "hit enter in urlbar: not in editing mode");
|
||||
}
|
||||
});
|
||||
|
||||
gTests.push({
|
||||
desc: "display and select a search with keyboard",
|
||||
setUp: setUp,
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1005 B |
|
@ -20,9 +20,12 @@
|
|||
.side-menu-widget-item-checkbox {
|
||||
-moz-appearance: none;
|
||||
padding: 0;
|
||||
margin: 0 -4px 0 4px;
|
||||
margin-top: 4px;
|
||||
margin-bottom: -4px;
|
||||
-moz-margin-start: 4px;
|
||||
-moz-margin-end: -4px;
|
||||
opacity: 0;
|
||||
transition: opacity .25s ease 0s;
|
||||
transition: opacity .15s ease 0s;
|
||||
}
|
||||
|
||||
/* Only show the checkbox when the source is hovered over, is selected, or if it
|
||||
|
@ -31,18 +34,18 @@
|
|||
.side-menu-widget-item.selected > .side-menu-widget-item-checkbox,
|
||||
.side-menu-widget-item-checkbox:not([checked]) {
|
||||
opacity: 1;
|
||||
transition: opacity .25s ease 0s;
|
||||
transition: opacity .15s ease 0s;
|
||||
}
|
||||
|
||||
.side-menu-widget-item-checkbox > .checkbox-check {
|
||||
-moz-appearance: none;
|
||||
background: none;
|
||||
background-image: url(itemToggle.png);
|
||||
background-image: url(blackbox.png);
|
||||
background-repeat: no-repeat;
|
||||
background-clip: content-box;
|
||||
background-position: -24px 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background-position: -16px 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
|
@ -61,9 +64,9 @@
|
|||
/* Black box message */
|
||||
|
||||
#black-boxed-message {
|
||||
background: url(background-noise-toolbar.png) rgb(61,69,76);
|
||||
/* Prevent the container deck from aquiring the height from this message. */
|
||||
min-height: 1px;
|
||||
background-color: rgb(61,69,76);
|
||||
padding: 25vh 0;
|
||||
color: white;
|
||||
}
|
||||
|
@ -125,6 +128,7 @@
|
|||
|
||||
.dbg-breakpoint {
|
||||
font-family: monospace;
|
||||
-moz-margin-start: -14px;
|
||||
}
|
||||
|
||||
.dbg-breakpoint-line {
|
||||
|
|
|
@ -353,7 +353,6 @@
|
|||
|
||||
.side-menu-widget-item-other {
|
||||
background: url(background-noise-toolbar.png), hsla(208,11%,27%, 0.65);
|
||||
-moz-margin-start: -22px;
|
||||
}
|
||||
|
||||
.side-menu-widget-item-other.selected {
|
||||
|
|
|
@ -179,6 +179,7 @@ browser.jar:
|
|||
skin/classic/browser/devtools/magnifying-glass.png (devtools/magnifying-glass.png)
|
||||
skin/classic/browser/devtools/option-icon.png (devtools/option-icon.png)
|
||||
skin/classic/browser/devtools/itemToggle.png (devtools/itemToggle.png)
|
||||
skin/classic/browser/devtools/blackbox.png (devtools/blackbox.png)
|
||||
skin/classic/browser/devtools/blackBoxMessageEye.png (devtools/blackBoxMessageEye.png)
|
||||
skin/classic/browser/devtools/itemArrow-rtl.png (devtools/itemArrow-rtl.png)
|
||||
skin/classic/browser/devtools/itemArrow-ltr.png (devtools/itemArrow-ltr.png)
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1005 B |
|
@ -22,9 +22,12 @@
|
|||
.side-menu-widget-item-checkbox {
|
||||
-moz-appearance: none;
|
||||
padding: 0;
|
||||
margin: 0 -4px 0 4px;
|
||||
margin-top: 4px;
|
||||
margin-bottom: -4px;
|
||||
-moz-margin-start: 4px;
|
||||
-moz-margin-end: -4px;
|
||||
opacity: 0;
|
||||
transition: opacity .25s ease-out 0s;
|
||||
transition: opacity .15s ease-out 0s;
|
||||
}
|
||||
|
||||
/* Only show the checkbox when the source is hovered over, is selected, or if it
|
||||
|
@ -33,18 +36,18 @@
|
|||
.side-menu-widget-item.selected > .side-menu-widget-item-checkbox,
|
||||
.side-menu-widget-item-checkbox:not([checked]) {
|
||||
opacity: 1;
|
||||
transition: opacity .25s ease-out 0s;
|
||||
transition: opacity .15s ease-out 0s;
|
||||
}
|
||||
|
||||
.side-menu-widget-item-checkbox > .checkbox-check {
|
||||
-moz-appearance: none;
|
||||
background: none;
|
||||
background-image: url(itemToggle.png);
|
||||
background-image: url(blackbox.png);
|
||||
background-repeat: no-repeat;
|
||||
background-clip: content-box;
|
||||
background-position: -24px 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background-position: -16px 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
|
@ -63,9 +66,9 @@
|
|||
/* Black box message */
|
||||
|
||||
#black-boxed-message {
|
||||
background: url(background-noise-toolbar.png) rgb(61,69,76);
|
||||
/* Prevent the container deck from aquiring the height from this message. */
|
||||
min-height: 1px;
|
||||
background-color: rgb(61,69,76);
|
||||
padding: 25vh 0;
|
||||
color: white;
|
||||
}
|
||||
|
@ -127,6 +130,7 @@
|
|||
|
||||
.dbg-breakpoint {
|
||||
font-family: monospace;
|
||||
-moz-margin-start: -14px;
|
||||
}
|
||||
|
||||
.dbg-breakpoint-line {
|
||||
|
|
|
@ -353,7 +353,6 @@
|
|||
|
||||
.side-menu-widget-item-other {
|
||||
background: url(background-noise-toolbar.png), hsla(208,11%,27%, 0.65);
|
||||
-moz-margin-start: -22px;
|
||||
}
|
||||
|
||||
.side-menu-widget-item-other.selected {
|
||||
|
|
|
@ -270,6 +270,7 @@ browser.jar:
|
|||
skin/classic/browser/devtools/magnifying-glass.png (devtools/magnifying-glass.png)
|
||||
skin/classic/browser/devtools/option-icon.png (devtools/option-icon.png)
|
||||
skin/classic/browser/devtools/itemToggle.png (devtools/itemToggle.png)
|
||||
skin/classic/browser/devtools/blackbox.png (devtools/blackbox.png)
|
||||
skin/classic/browser/devtools/blackBoxMessageEye.png (devtools/blackBoxMessageEye.png)
|
||||
skin/classic/browser/devtools/itemArrow-rtl.png (devtools/itemArrow-rtl.png)
|
||||
skin/classic/browser/devtools/itemArrow-ltr.png (devtools/itemArrow-ltr.png)
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1005 B |
|
@ -20,9 +20,12 @@
|
|||
.side-menu-widget-item-checkbox {
|
||||
-moz-appearance: none;
|
||||
padding: 0;
|
||||
margin: 0 -4px 0 4px;
|
||||
margin-top: 4px;
|
||||
margin-bottom: -4px;
|
||||
-moz-margin-start: 4px;
|
||||
-moz-margin-end: -4px;
|
||||
opacity: 0;
|
||||
transition: opacity .25s ease 0s;
|
||||
transition: opacity .15s ease 0s;
|
||||
}
|
||||
|
||||
/* Only show the checkbox when the source is hovered over, is selected, or if it
|
||||
|
@ -31,18 +34,18 @@
|
|||
.side-menu-widget-item.selected > .side-menu-widget-item-checkbox,
|
||||
.side-menu-widget-item-checkbox:not([checked]) {
|
||||
opacity: 1;
|
||||
transition: opacity .25s ease-out 0s;
|
||||
transition: opacity .15s ease-out 0s;
|
||||
}
|
||||
|
||||
.side-menu-widget-item-checkbox > .checkbox-check {
|
||||
-moz-appearance: none;
|
||||
background: none;
|
||||
background-image: url(itemToggle.png);
|
||||
background-image: url(blackbox.png);
|
||||
background-repeat: no-repeat;
|
||||
background-clip: content-box;
|
||||
background-position: -24px 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background-position: -16px 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
|
@ -61,9 +64,9 @@
|
|||
/* Black box message */
|
||||
|
||||
#black-boxed-message {
|
||||
background: url(background-noise-toolbar.png) rgb(61,69,76);
|
||||
/* Prevent the container deck from aquiring the height from this message. */
|
||||
min-height: 1px;
|
||||
background-color: rgb(61,69,76);
|
||||
padding: 25vh 0;
|
||||
color: white;
|
||||
}
|
||||
|
@ -125,6 +128,7 @@
|
|||
|
||||
.dbg-breakpoint {
|
||||
font-family: monospace;
|
||||
-moz-margin-start: -14px;
|
||||
}
|
||||
|
||||
.dbg-breakpoint-line {
|
||||
|
|
|
@ -357,7 +357,6 @@
|
|||
|
||||
.side-menu-widget-item-other {
|
||||
background: url(background-noise-toolbar.png), hsla(208,11%,27%, 0.65);
|
||||
-moz-margin-start: -22px;
|
||||
}
|
||||
|
||||
.side-menu-widget-item-other.selected {
|
||||
|
|
|
@ -206,6 +206,7 @@ browser.jar:
|
|||
skin/classic/browser/devtools/magnifying-glass.png (devtools/magnifying-glass.png)
|
||||
skin/classic/browser/devtools/option-icon.png (devtools/option-icon.png)
|
||||
skin/classic/browser/devtools/itemToggle.png (devtools/itemToggle.png)
|
||||
skin/classic/browser/devtools/blackbox.png (devtools/blackbox.png)
|
||||
skin/classic/browser/devtools/blackBoxMessageEye.png (devtools/blackBoxMessageEye.png)
|
||||
skin/classic/browser/devtools/itemArrow-rtl.png (devtools/itemArrow-rtl.png)
|
||||
skin/classic/browser/devtools/itemArrow-ltr.png (devtools/itemArrow-ltr.png)
|
||||
|
@ -464,6 +465,7 @@ browser.jar:
|
|||
skin/classic/aero/browser/devtools/magnifying-glass.png (devtools/magnifying-glass.png)
|
||||
skin/classic/aero/browser/devtools/option-icon.png (devtools/option-icon.png)
|
||||
skin/classic/aero/browser/devtools/itemToggle.png (devtools/itemToggle.png)
|
||||
skin/classic/browser/devtools/blackbox.png (devtools/blackbox.png)
|
||||
skin/classic/aero/browser/devtools/blackBoxMessageEye.png (devtools/blackBoxMessageEye.png)
|
||||
skin/classic/aero/browser/devtools/itemArrow-rtl.png (devtools/itemArrow-rtl.png)
|
||||
skin/classic/aero/browser/devtools/background-noise-toolbar.png (devtools/background-noise-toolbar.png)
|
||||
|
|
|
@ -32,6 +32,7 @@ IndexedDBHelper.prototype = {
|
|||
close: function close() {
|
||||
if (this._db) {
|
||||
this._db.close();
|
||||
this._db = null;
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ['ContactDB'];
|
||||
// Everything but "ContactDB" is only exported here for testing.
|
||||
this.EXPORTED_SYMBOLS = ["ContactDB", "DB_NAME", "STORE_NAME", "SAVED_GETALL_STORE_NAME",
|
||||
"REVISION_STORE", "DB_VERSION"];
|
||||
|
||||
const DEBUG = false;
|
||||
function debug(s) { dump("-*- ContactDB component: " + s + "\n"); }
|
||||
|
@ -95,16 +97,17 @@ function ContactDispatcher(aContacts, aFullContacts, aCallback, aNewTxn, aClearD
|
|||
};
|
||||
}
|
||||
|
||||
this.ContactDB = function ContactDB(aGlobal) {
|
||||
this.ContactDB = function ContactDB() {
|
||||
if (DEBUG) debug("Constructor");
|
||||
this._global = aGlobal;
|
||||
}
|
||||
};
|
||||
|
||||
ContactDB.prototype = {
|
||||
__proto__: IndexedDBHelper.prototype,
|
||||
|
||||
_dispatcher: {},
|
||||
|
||||
useFastUpgrade: true,
|
||||
|
||||
upgradeSchema: function upgradeSchema(aTransaction, aDb, aOldVersion, aNewVersion) {
|
||||
let loadInitialContacts = function() {
|
||||
// Add default contacts
|
||||
|
@ -157,10 +160,33 @@ ContactDB.prototype = {
|
|||
}
|
||||
}.bind(this);
|
||||
|
||||
function createFinalSchema() {
|
||||
if (DEBUG) debug("creating final schema");
|
||||
let objectStore = aDb.createObjectStore(STORE_NAME, {keyPath: "id"});
|
||||
objectStore.createIndex("familyName", "properties.familyName", { multiEntry: true });
|
||||
objectStore.createIndex("givenName", "properties.givenName", { multiEntry: true });
|
||||
objectStore.createIndex("familyNameLowerCase", "search.familyName", { multiEntry: true });
|
||||
objectStore.createIndex("givenNameLowerCase", "search.givenName", { multiEntry: true });
|
||||
objectStore.createIndex("telLowerCase", "search.tel", { multiEntry: true });
|
||||
objectStore.createIndex("emailLowerCase", "search.email", { multiEntry: true });
|
||||
objectStore.createIndex("tel", "search.exactTel", { multiEntry: true });
|
||||
objectStore.createIndex("category", "properties.category", { multiEntry: true });
|
||||
objectStore.createIndex("email", "search.email", { multiEntry: true });
|
||||
objectStore.createIndex("telMatch", "search.parsedTel", {multiEntry: true});
|
||||
aDb.createObjectStore(SAVED_GETALL_STORE_NAME);
|
||||
aDb.createObjectStore(REVISION_STORE).put(0, REVISION_KEY);
|
||||
}
|
||||
|
||||
if (DEBUG) debug("upgrade schema from: " + aOldVersion + " to " + aNewVersion + " called!");
|
||||
let db = aDb;
|
||||
let objectStore;
|
||||
|
||||
if (aOldVersion === 0 && this.useFastUpgrade) {
|
||||
createFinalSchema();
|
||||
loadInitialContacts();
|
||||
return;
|
||||
}
|
||||
|
||||
let steps = [
|
||||
function upgrade0to1() {
|
||||
/**
|
||||
|
@ -529,9 +555,6 @@ ContactDB.prototype = {
|
|||
let outer = this;
|
||||
function next() {
|
||||
if (index == aNewVersion) {
|
||||
if (aOldVersion === 0) {
|
||||
loadInitialContacts();
|
||||
}
|
||||
outer.incrementRevision(aTransaction);
|
||||
return;
|
||||
}
|
||||
|
@ -1053,7 +1076,7 @@ ContactDB.prototype = {
|
|||
}
|
||||
}
|
||||
if (DEBUG) debug("lowerCase: " + lowerCase);
|
||||
let range = this._global.IDBKeyRange.bound(lowerCase, lowerCase + "\uFFFF");
|
||||
let range = this.dbGlobal.IDBKeyRange.bound(lowerCase, lowerCase + "\uFFFF");
|
||||
let index = store.index(key + "LowerCase");
|
||||
request = index.mozGetAll(range, limit);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ let ContactService = {
|
|||
|
||||
var idbManager = Components.classes["@mozilla.org/dom/indexeddb/manager;1"].getService(Ci.nsIIndexedDatabaseManager);
|
||||
idbManager.initWindowless(myGlobal);
|
||||
this._db = new ContactDB(myGlobal);
|
||||
this._db = new ContactDB();
|
||||
this._db.init(myGlobal);
|
||||
|
||||
this.configureSubstringMatching();
|
||||
|
|
|
@ -20,5 +20,9 @@ MOCHITEST_FILES = \
|
|||
test_contacts_getall.html \
|
||||
$(NULL)
|
||||
|
||||
MOCHITEST_CHROME_FILES = \
|
||||
test_contacts_upgrade.html \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
|
|
@ -0,0 +1,274 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=889239
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 889239</title>
|
||||
<script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=889239">Mozilla Bug 889239</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript;version=1.7">
|
||||
"use strict";
|
||||
|
||||
function checkStr(str1, str2, msg) {
|
||||
if (str1 ^ str2) {
|
||||
ok(false, "Expected both strings to be either present or absent");
|
||||
return;
|
||||
}
|
||||
is(str1, str2, msg);
|
||||
}
|
||||
|
||||
function checkStrArray(str1, str2, msg) {
|
||||
// comparing /[null(,null)+]/ and undefined should pass
|
||||
function nonNull(e) {
|
||||
return e != null;
|
||||
}
|
||||
if ((Array.isArray(str1) && str1.filter(nonNull).length == 0 && str2 == undefined)
|
||||
||(Array.isArray(str2) && str2.filter(nonNull).length == 0 && str1 == undefined)) {
|
||||
ok(true, msg);
|
||||
} else if (str1) {
|
||||
is(JSON.stringify(typeof str1 == "string" ? [str1] : str1), JSON.stringify(typeof str2 == "string" ? [str2] : str2), msg);
|
||||
}
|
||||
}
|
||||
|
||||
function checkAddress(adr1, adr2) {
|
||||
if (adr1 ^ adr2) {
|
||||
ok(false, "Expected both adrs to be either present or absent");
|
||||
return;
|
||||
}
|
||||
checkStrArray(adr1.type, adr2.type, "Same type");
|
||||
checkStrArray(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
|
||||
checkStrArray(adr1.locality, adr2.locality, "Same locality");
|
||||
checkStrArray(adr1.region, adr2.region, "Same region");
|
||||
checkStrArray(adr1.postalCode, adr2.postalCode, "Same postalCode");
|
||||
checkStrArray(adr1.countryName, adr2.countryName, "Same countryName");
|
||||
is(adr1.pref, adr2.pref, "Same pref");
|
||||
}
|
||||
|
||||
function checkTel(tel1, tel2) {
|
||||
if (tel1 ^ tel2) {
|
||||
ok(false, "Expected both tels to be either present or absent");
|
||||
return;
|
||||
}
|
||||
checkStrArray(tel1.type, tel2.type, "Same type");
|
||||
checkStrArray(tel1.value, tel2.value, "Same value");
|
||||
checkStrArray(tel1.carrier, tel2.carrier, "Same carrier");
|
||||
is(tel1.pref, tel2.pref, "Same pref");
|
||||
}
|
||||
|
||||
function checkField(field1, field2) {
|
||||
if (field1 ^ field2) {
|
||||
ok(false, "Expected both fields to be either present or absent");
|
||||
return;
|
||||
}
|
||||
checkStrArray(field1.type, field2.type, "Same type");
|
||||
checkStrArray(field1.value, field2.value, "Same value");
|
||||
is(field1.pref, field2.pref, "Same pref");
|
||||
}
|
||||
|
||||
function checkDBContacts(dbContact1, dbContact2) {
|
||||
let contact1 = dbContact1.properties;
|
||||
let contact2 = dbContact2.properties;
|
||||
|
||||
checkStrArray(contact1.name, contact2.name, "Same name");
|
||||
checkStrArray(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
|
||||
checkStrArray(contact1.givenName, contact2.givenName, "Same givenName");
|
||||
checkStrArray(contact1.additionalName, contact2.additionalName, "Same additionalName");
|
||||
checkStrArray(contact1.familyName, contact2.familyName, "Same familyName");
|
||||
checkStrArray(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
|
||||
checkStrArray(contact1.nickname, contact2.nickname, "Same nickname");
|
||||
checkStrArray(contact1.category, contact2.category, "Same category");
|
||||
checkStrArray(contact1.org, contact2.org, "Same org");
|
||||
checkStrArray(contact1.jobTitle, contact2.jobTitle, "Same jobTitle");
|
||||
is(contact1.bday ? contact1.bday.valueOf() : null, contact2.bday ? contact2.bday.valueOf() : null, "Same birthday");
|
||||
checkStrArray(contact1.note, contact2.note, "Same note");
|
||||
is(contact1.anniversary ? contact1.anniversary.valueOf() : null , contact2.anniversary ? contact2.anniversary.valueOf() : null, "Same anniversary");
|
||||
checkStr(contact1.sex, contact2.sex, "Same sex");
|
||||
checkStr(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
|
||||
checkStrArray(contact1.key, contact2.key, "Same key");
|
||||
|
||||
is(contact1.email.length, contact2.email.length, "Same number of emails");
|
||||
for (let i = 0; i < contact1.email.length; ++i) {
|
||||
checkField(contact1.email[i], contact2.email[i]);
|
||||
}
|
||||
|
||||
is(contact1.adr.length, contact2.adr.length, "Same number of adrs");
|
||||
for (var i in contact1.adr) {
|
||||
checkAddress(contact1.adr[i], contact2.adr[i]);
|
||||
}
|
||||
|
||||
is(contact1.tel.length, contact2.tel.length, "Same number of tels");
|
||||
for (var i in contact1.tel) {
|
||||
checkTel(contact1.tel[i], contact2.tel[i]);
|
||||
}
|
||||
|
||||
is(contact1.url.length, contact2.url.length, "Same number of urls");
|
||||
for (var i in contact1.url) {
|
||||
checkField(contact1.url[i], contact2.url[i]);
|
||||
}
|
||||
|
||||
is(contact1.impp.length, contact2.impp.length, "Same number of impps");
|
||||
for (var i in contact1.impp) {
|
||||
checkField(contact1.impp[i], contact2.impp[i]);
|
||||
}
|
||||
|
||||
// test search indexes
|
||||
contact1 = dbContact1.search;
|
||||
contact2 = dbContact2.search;
|
||||
checkStrArray(contact1.category, contact2.category, "Same cateogry index");
|
||||
checkStrArray(contact1.email, contact2.email, "Same email index");
|
||||
checkStrArray(contact1.emailLowerCase, contact2.emailLowerCase, "Same emailLowerCase index");
|
||||
checkStrArray(contact1.familyName, contact2.familyName, "Same familyName index");
|
||||
checkStrArray(contact1.familyNameLowerCase, contact2.familyNameLowerCase, "Same familyNameLowerCase index");
|
||||
checkStrArray(contact1.givenName, contact2.givenName, "Same givenName index");
|
||||
checkStrArray(contact1.givenNameLowerCase, contact2.givenNameLowerCase, "Same givenNameLowerCase index");
|
||||
checkStrArray(contact1.tel, contact2.tel, "Same tel index");
|
||||
checkStrArray(contact1.telLowerCase, contact2.telLowerCase, "Same telLowerCase index");
|
||||
checkStrArray(contact1.telMatch, contact2.telMatch, "Same telMatch index");
|
||||
}
|
||||
|
||||
function makeFailure(reason) {
|
||||
return function() {
|
||||
ok(false, reason);
|
||||
SimpleTest.finish();
|
||||
};
|
||||
};
|
||||
|
||||
const {Cc, Ci, Cu} = SpecialPowers;
|
||||
Cu.import("resource://gre/modules/ContactDB.jsm", window);
|
||||
|
||||
let idb = {};
|
||||
Cc["@mozilla.org/dom/indexeddb/manager;1"]
|
||||
.getService(Ci.nsIIndexedDatabaseManager)
|
||||
.initWindowless(idb);
|
||||
|
||||
let cdb = new ContactDB();
|
||||
cdb.init(idb);
|
||||
|
||||
let CONTACT_PROPS = {
|
||||
id: "ab74671e36be41b680f8f030e7e24ea2",
|
||||
properties: {
|
||||
name: ["magnificentest foo bar the third"],
|
||||
givenName: ["foo"],
|
||||
familyName: ["bar"],
|
||||
honorificPrefix: ["magnificentest"],
|
||||
honorificSuffix: ["the third"],
|
||||
additionalName: ["addl"],
|
||||
nickname: ["foo"],
|
||||
tel: [
|
||||
{type: ["mobile"], value: "+12345678901", carrier: "ACME Telecommunications", pref: true},
|
||||
{type: ["home", "custom"], value: "7932012346", pref: false},
|
||||
],
|
||||
email: [{type: ["work"], value: "a@b.c"}, {value: "b@c.d", pref: true}],
|
||||
adr: [
|
||||
{
|
||||
type: ["home"],
|
||||
streetAddress: "street 1",
|
||||
locality: "locality 1",
|
||||
region: "region 1",
|
||||
postalCode: "postal code 1",
|
||||
countryName: "country 1",
|
||||
}
|
||||
],
|
||||
impp: [{type: ["aim"], value:"im1", pref: true}, {value: "im2"}],
|
||||
org: ["org1", "org2"],
|
||||
jobTitle: ["boss", "superboss"],
|
||||
bday: new Date("1980, 12, 01"),
|
||||
note: ["bla bla bla"],
|
||||
category: ["cat1", "cat2"],
|
||||
url: [{type: ["work", "work2"], value: "www.1.com", pref: true}, {value: "www2.com"}],
|
||||
anniversary: new Date("2000, 12, 01"),
|
||||
sex: "male",
|
||||
genderIdentity: "trisexual",
|
||||
key: "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAC4jAAAuIwF4pT92AAACrElEQVQozwXBTW8bRRgA4Hfemf1er7/iJI4Tq7VFlEZN1VZIlapy4MQBTkXcuSH+G/APKnGAAyCVCqmtCHETp64db5zdtdf7NbMzw/OQH378HkCZpmmapqYMy8yrNnadS6026HC/Z7k+SCkEBwKEEKaUQtQAmlDqrucH23nH4BRkJVRcwmod5gcn6LehFgCaEIIalFZaEcLCq73w355RdvY7nfGQGVTlmRXfqMlrUaSUMUQkhCISJIggKj3/YBHt7PRbpy+cwbF7dN/0vEqTMoo3s0tmGAAAoJAgImMq3xZ5WTPbHj4Mho8Nf+QcPtZBLxEkqeQ2WmklkRCtNdNaI1KpVCnqOC3j5ZK++4vnm6xSWZpzwQtRV2mOiBoRpEKtNQAQggjQcCwqinRxJeKlWW93dlqEsa2QRZbF85nWBAAZY4YUgl9fRJWKVuWgmhwHhpD1+ZrfVjAN867rMCne//rq7OuXjWaLCVHnOWHgFDwMw+Tvi09PdhtJXoVC7bWDIi8Lg8qyMk3rYjLzvJh2O30hwK6TpiG7zWDcck9GR17D9wxDcH7/oNtElRa1aZuLDJN4S7/87tssLVg0/eZs/3h0D5R89vR0v+1AVT0YHX31ZDy9uv7IeJrryeyu2+nS50/PqOXM5qt8Nf/jv08UwTfN27vkchldLpPf/nx/nqSz5sbzhkTYzLRppzNYre/ycrMIZwqsHdf96fd/Xr354AYBr/jESWhgGb6zVSuGrrQS1j4Zk8nc2Hs7frFb3Phc6+fOKDGLKOJTHvlj2u85N4t6vbw7OM4YRVquboPdsPNZ9eb8pvfAOf2iN4dN3EzWadnoO5JY19Oo0TYtw1t8TBqBR9v7wbOXROLWtZ3PH937+ZfXrb6BUHEbXL+FCIfDw92e5zebg8GR54r/AaMVcBxE6hgPAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDEyLTA3LTIxVDEwOjUzOjE5LTA0OjAwYyXbYgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxMi0wNy0yMVQxMDo1MzoxOS0wNDowMBJ4Y94AAAARdEVYdGpwZWc6Y29sb3JzcGFjZQAyLHVVnwAAACB0RVh0anBlZzpzYW1wbGluZy1mYWN0b3IAMXgxLDF4MSwxeDHplfxwAAAAAElFTkSuQmCC"
|
||||
}
|
||||
};
|
||||
|
||||
function deleteDatabase(then) {
|
||||
cdb.close();
|
||||
let req = idb.indexedDB.deleteDatabase(DB_NAME);
|
||||
req.onsuccess = then;
|
||||
req.onblocked = makeFailure("blocked");
|
||||
req.onupgradeneeded = makeFailure("onupgradeneeded");
|
||||
req.onerror = makeFailure("onerror");
|
||||
}
|
||||
|
||||
function saveContact() {
|
||||
// takes fast upgrade path
|
||||
cdb.saveContact(CONTACT_PROPS,
|
||||
function() {
|
||||
ok(true, "Saved contact successfully");
|
||||
next();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getContact(callback) {
|
||||
return function() {
|
||||
let req = idb.indexedDB.open(STORE_NAME, DB_VERSION);
|
||||
req.onsuccess = function(event) {
|
||||
let db = event.target.result;
|
||||
let txn = db.transaction([STORE_NAME], "readonly");
|
||||
txn.onabort = makeFailure("Failed to open transaction");
|
||||
let r2 = txn.objectStore(STORE_NAME).get(CONTACT_PROPS.id);
|
||||
r2.onsuccess = function() {
|
||||
db.close();
|
||||
callback(r2.result);
|
||||
};
|
||||
r2.onerror = makeFailure("Failed to get contact");
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
let savedContact;
|
||||
|
||||
let Tests = [
|
||||
saveContact,
|
||||
|
||||
getContact(function(contact) {
|
||||
savedContact = contact;
|
||||
next();
|
||||
}),
|
||||
|
||||
function() {
|
||||
deleteDatabase(function() {
|
||||
info("slow upgrade");
|
||||
cdb.useFastUpgrade = false;
|
||||
cdb.init(idb);
|
||||
next();
|
||||
});
|
||||
},
|
||||
|
||||
saveContact,
|
||||
|
||||
getContact(function(contact) {
|
||||
checkDBContacts(savedContact, contact);
|
||||
next();
|
||||
}),
|
||||
];
|
||||
|
||||
function next() {
|
||||
let step = Tests.shift();
|
||||
if (step) {
|
||||
step();
|
||||
} else {
|
||||
info("All done");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
next();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -3543,10 +3543,6 @@ RadioInterface.prototype = {
|
|||
reason: reason});
|
||||
},
|
||||
|
||||
getDataCallList: function getDataCallList() {
|
||||
this.worker.postMessage({rilMessageType: "getDataCallList"});
|
||||
},
|
||||
|
||||
getCardLockState: function getCardLockState(message) {
|
||||
message.rilMessageType = "iccGetCardLockState";
|
||||
this.worker.postMessage(message);
|
||||
|
|
|
@ -79,33 +79,17 @@ interface nsIRilContext : nsISupports
|
|||
readonly attribute nsIDOMMozMobileConnectionInfo data;
|
||||
};
|
||||
|
||||
[scriptable, uuid(715c972b-97c5-48fd-a8b1-d50e6852153a)]
|
||||
[scriptable, uuid(5efcd358-080e-46d6-a7f7-4f36c204eec3)]
|
||||
interface nsIRadioInterface : nsISupports
|
||||
{
|
||||
/**
|
||||
* Activates or deactivates radio power.
|
||||
*/
|
||||
void setRadioEnabled(in bool value);
|
||||
|
||||
readonly attribute nsIRilContext rilContext;
|
||||
|
||||
readonly attribute nsIVoicemailInfo voicemailInfo;
|
||||
|
||||
/**
|
||||
* PDP APIs
|
||||
*/
|
||||
void setupDataCallByType(in DOMString apntype);
|
||||
void deactivateDataCallByType(in DOMString apntype);
|
||||
long getDataCallStateByType(in DOMString apntype);
|
||||
void setupDataCall(in long radioTech,
|
||||
in DOMString apn,
|
||||
in DOMString user,
|
||||
in DOMString passwd,
|
||||
in long chappap,
|
||||
in DOMString pdptype);
|
||||
void deactivateDataCall(in DOMString cid,
|
||||
in DOMString reason);
|
||||
void getDataCallList();
|
||||
|
||||
void registerDataCallCallback(in nsIRILDataCallback callback);
|
||||
void unregisterDataCallCallback(in nsIRILDataCallback callback);
|
||||
|
|
|
@ -5,6 +5,5 @@ qemu = true
|
|||
|
||||
[test_geolocation.js]
|
||||
disabled = Bug 808783
|
||||
[test_get_voicemailInfo.js]
|
||||
[test_fakevolume.js]
|
||||
[test_ril_code_quality.py]
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 10000;
|
||||
|
||||
let Cc = SpecialPowers.Cc;
|
||||
let Ci = SpecialPowers.Ci;
|
||||
|
||||
// Get RadioInterfaceLayer interface.
|
||||
let radioInterfaceLayer =
|
||||
Cc["@mozilla.org/ril;1"].getService(Ci.nsIRadioInterfaceLayer);
|
||||
ok(radioInterfaceLayer);
|
||||
|
||||
// Get RadioInterface.
|
||||
let radioInterface = radioInterfaceLayer.getRadioInterface(0);
|
||||
ok(radioInterface);
|
||||
|
||||
// Check voicemail information accessible.
|
||||
ok(radioInterface.voicemailInfo);
|
||||
ok(radioInterface.voicemailInfo.number);
|
||||
ok(radioInterface.voicemailInfo.displayName);
|
||||
// These are the emulator's hard coded voicemail number and alphaId.
|
||||
is(radioInterface.voicemailInfo.number, "+15552175049");
|
||||
is(radioInterface.voicemailInfo.displayName, "Voicemail");
|
||||
|
||||
finish();
|
|
@ -154,7 +154,6 @@ abstract public class GeckoApp
|
|||
public static final String ACTION_LOAD = "org.mozilla.gecko.LOAD";
|
||||
public static final String ACTION_LAUNCH_SETTINGS = "org.mozilla.gecko.SETTINGS";
|
||||
public static final String ACTION_INIT_PW = "org.mozilla.gecko.INIT_PW";
|
||||
public static final String SAVED_STATE_INTENT_HANDLED = "intentHandled";
|
||||
public static final String SAVED_STATE_IN_BACKGROUND = "inBackground";
|
||||
public static final String SAVED_STATE_PRIVATE_SESSION = "privateSession";
|
||||
|
||||
|
@ -186,7 +185,6 @@ abstract public class GeckoApp
|
|||
protected GeckoProfile mProfile;
|
||||
public static int mOrientation;
|
||||
protected boolean mIsRestoringActivity;
|
||||
private boolean mIntentHandled;
|
||||
private String mCurrentResponse = "";
|
||||
public static boolean sIsUsingCustomProfile = false;
|
||||
|
||||
|
@ -492,11 +490,6 @@ abstract public class GeckoApp
|
|||
|
||||
outState.putBoolean(SAVED_STATE_IN_BACKGROUND, isApplicationInBackground());
|
||||
outState.putString(SAVED_STATE_PRIVATE_SESSION, mPrivateBrowsingSession);
|
||||
|
||||
// Bug 896992 - Replace intent action with ACTION_MAIN on restart.
|
||||
if (mIntentHandled) {
|
||||
outState.putBoolean(SAVED_STATE_INTENT_HANDLED, true);
|
||||
}
|
||||
}
|
||||
|
||||
void handleFaviconRequest(final String url) {
|
||||
|
@ -1278,19 +1271,14 @@ abstract public class GeckoApp
|
|||
Telemetry.HistogramAdd("FENNEC_WAS_KILLED", 1);
|
||||
}
|
||||
|
||||
if (savedInstanceState.getBoolean(SAVED_STATE_INTENT_HANDLED, false)) {
|
||||
Intent thisIntent = getIntent();
|
||||
// Bug 896992 - This intent has already been handled, clear the intent action.
|
||||
thisIntent.setAction(Intent.ACTION_MAIN);
|
||||
setIntent(thisIntent);
|
||||
|
||||
// Persist this flag for reincarnations of this Activity Intent.
|
||||
mIntentHandled = true;
|
||||
}
|
||||
|
||||
mPrivateBrowsingSession = savedInstanceState.getString(SAVED_STATE_PRIVATE_SESSION);
|
||||
}
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
// Bug 896992 - This intent has already been handled; reset the intent.
|
||||
setIntent(new Intent(Intent.ACTION_MAIN));
|
||||
}
|
||||
|
||||
// Perform background initialization.
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
|
@ -1432,8 +1420,12 @@ abstract public class GeckoApp
|
|||
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Session:Restore", restoreMessage));
|
||||
|
||||
if (!mIsRestoringActivity) {
|
||||
loadStartupTab(isExternalURL ? passedUri : null);
|
||||
// External URLs should always be loaded regardless of whether Gecko is
|
||||
// already running.
|
||||
if (isExternalURL) {
|
||||
loadStartupTab(passedUri);
|
||||
} else if (!mIsRestoringActivity) {
|
||||
loadStartupTab(null);
|
||||
}
|
||||
|
||||
if (mRestoreMode == RESTORE_NORMAL) {
|
||||
|
@ -1472,7 +1464,6 @@ abstract public class GeckoApp
|
|||
|
||||
// Check if launched from data reporting notification.
|
||||
if (ACTION_LAUNCH_SETTINGS.equals(action)) {
|
||||
mIntentHandled = true;
|
||||
Intent settingsIntent = new Intent(GeckoApp.this, GeckoPreferences.class);
|
||||
// Copy extras.
|
||||
settingsIntent.putExtras(intent);
|
||||
|
@ -1867,15 +1858,9 @@ abstract public class GeckoApp
|
|||
return;
|
||||
}
|
||||
|
||||
// don't perform any actions if launching from recent apps
|
||||
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0)
|
||||
return;
|
||||
|
||||
final String action = intent.getAction();
|
||||
|
||||
if (Intent.ACTION_MAIN.equals(action)) {
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createURILoadEvent(""));
|
||||
} else if (ACTION_LOAD.equals(action)) {
|
||||
if (ACTION_LOAD.equals(action)) {
|
||||
String uri = intent.getDataString();
|
||||
Tabs.getInstance().loadUrl(uri);
|
||||
} else if (Intent.ACTION_VIEW.equals(action)) {
|
||||
|
@ -1893,7 +1878,6 @@ abstract public class GeckoApp
|
|||
} else if (ACTION_ALERT_CALLBACK.equals(action)) {
|
||||
processAlertCallback(intent);
|
||||
} else if (ACTION_LAUNCH_SETTINGS.equals(action)) {
|
||||
mIntentHandled = true;
|
||||
// Check if launched from data reporting notification.
|
||||
Intent settingsIntent = new Intent(GeckoApp.this, GeckoPreferences.class);
|
||||
// Copy extras.
|
||||
|
|
|
@ -60,6 +60,7 @@ const object = require("sdk/util/object");
|
|||
const events = require("sdk/event/core");
|
||||
const { Unknown } = require("sdk/platform/xpcom");
|
||||
const { Class } = require("sdk/core/heritage");
|
||||
const {PageStyleActor} = require("devtools/server/actors/styles");
|
||||
|
||||
const PSEUDO_CLASSES = [":hover", ":active", ":focus"];
|
||||
|
||||
|
@ -2080,7 +2081,8 @@ var InspectorActor = protocol.ActorClass({
|
|||
var domReady = () => {
|
||||
let tabActor = this.tabActor;
|
||||
window.removeEventListener("DOMContentLoaded", domReady, true);
|
||||
deferred.resolve(WalkerActor(this.conn, window.document, tabActor._tabbrowser, options));
|
||||
this.walker = WalkerActor(this.conn, window.document, tabActor._tabbrowser, options);
|
||||
deferred.resolve(this.walker);
|
||||
};
|
||||
|
||||
if (window.document.readyState === "loading") {
|
||||
|
@ -2095,6 +2097,20 @@ var InspectorActor = protocol.ActorClass({
|
|||
response: {
|
||||
walker: RetVal("domwalker")
|
||||
}
|
||||
}),
|
||||
|
||||
getPageStyle: method(function() {
|
||||
if (this._pageStylePromise) {
|
||||
return this._pageStylePromise;
|
||||
}
|
||||
|
||||
this._pageStylePromise = this.getWalker().then(walker => {
|
||||
return PageStyleActor(this);
|
||||
});
|
||||
return this._pageStylePromise;
|
||||
}, {
|
||||
request: {},
|
||||
response: { pageStyle: RetVal("pagestyle") }
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -2111,7 +2127,31 @@ var InspectorFront = exports.InspectorFront = protocol.FrontClass(InspectorActor
|
|||
// library, so we're going to self-own on the client side for now.
|
||||
client.addActorPool(this);
|
||||
this.manage(this);
|
||||
}
|
||||
},
|
||||
|
||||
getWalker: protocol.custom(function() {
|
||||
return this._getWalker().then(walker => {
|
||||
this.walker = walker;
|
||||
return walker;
|
||||
});
|
||||
}, {
|
||||
impl: "_getWalker"
|
||||
}),
|
||||
|
||||
getPageStyle: protocol.custom(function() {
|
||||
return this._getPageStyle().then(pageStyle => {
|
||||
// We need a walker to understand node references from the
|
||||
// node style.
|
||||
if (this.walker) {
|
||||
return pageStyle;
|
||||
}
|
||||
return this.getWalker().then(() => {
|
||||
return pageStyle;
|
||||
});
|
||||
});
|
||||
}, {
|
||||
impl: "_getPageStyle"
|
||||
})
|
||||
});
|
||||
|
||||
function documentWalker(node, whatToShow=Ci.nsIDOMNodeFilter.SHOW_ALL) {
|
||||
|
|
|
@ -0,0 +1,757 @@
|
|||
/* 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 {Cc, Ci} = require("chrome");
|
||||
const protocol = require("devtools/server/protocol");
|
||||
const {Arg, Option, method, RetVal, types} = protocol;
|
||||
const events = require("sdk/event/core");
|
||||
const object = require("sdk/util/object");
|
||||
const { Class } = require("sdk/core/heritage");
|
||||
|
||||
loader.lazyGetter(this, "CssLogic", () => require("devtools/styleinspector/css-logic").CssLogic);
|
||||
loader.lazyGetter(this, "DOMUtils", () => Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils));
|
||||
|
||||
// The PageStyle actor flattens the DOM CSS objects a little bit, merging
|
||||
// Rules and their Styles into one actor. For elements (which have a style
|
||||
// but no associated rule) we fake a rule with the following style id.
|
||||
const ELEMENT_STYLE = 100;
|
||||
exports.ELEMENT_STYLE = ELEMENT_STYLE;
|
||||
|
||||
// Predeclare the domnode actor type for use in requests.
|
||||
types.addActorType("domnode");
|
||||
|
||||
/**
|
||||
* DOM Nodes returned by the style actor will be owned by the DOM walker
|
||||
* for the connection.
|
||||
*/
|
||||
types.addLifetime("walker", "walker");
|
||||
|
||||
/**
|
||||
* When asking for the styles applied to a node, we return a list of
|
||||
* appliedstyle json objects that lists the rules that apply to the node
|
||||
* and which element they were inherited from (if any).
|
||||
*/
|
||||
types.addDictType("appliedstyle", {
|
||||
rule: "domstylerule#actorid",
|
||||
inherited: "nullable:domnode#actorid"
|
||||
});
|
||||
|
||||
types.addDictType("matchedselector", {
|
||||
rule: "domstylerule#actorid",
|
||||
selector: "string",
|
||||
value: "string",
|
||||
status: "number"
|
||||
});
|
||||
|
||||
/**
|
||||
* The PageStyle actor lets the client look at the styles on a page, as
|
||||
* they are applied to a given node.
|
||||
*/
|
||||
var PageStyleActor = protocol.ActorClass({
|
||||
typeName: "pagestyle",
|
||||
|
||||
/**
|
||||
* Create a PageStyleActor.
|
||||
*
|
||||
* @param inspector
|
||||
* The InspectorActor that owns this PageStyleActor.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
initialize: function(inspector) {
|
||||
protocol.Actor.prototype.initialize.call(this, null);
|
||||
this.inspector = inspector;
|
||||
if (!this.inspector.walker) {
|
||||
throw Error("The inspector's WalkerActor must be created before " +
|
||||
"creating a PageStyleActor.");
|
||||
}
|
||||
this.walker = inspector.walker;
|
||||
this.cssLogic = new CssLogic;
|
||||
|
||||
// Stores the association of DOM objects -> actors
|
||||
this.refMap = new Map;
|
||||
},
|
||||
|
||||
get conn() this.inspector.conn,
|
||||
|
||||
/**
|
||||
* Return or create a StyleRuleActor for the given item.
|
||||
* @param item Either a CSSStyleRule or a DOM element.
|
||||
*/
|
||||
_styleRef: function(item) {
|
||||
if (this.refMap.has(item)) {
|
||||
return this.refMap.get(item);
|
||||
}
|
||||
let actor = StyleRuleActor(this, item);
|
||||
this.manage(actor);
|
||||
this.refMap.set(item, actor);
|
||||
|
||||
return actor;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return or create a StyleSheetActor for the given
|
||||
* nsIDOMCSSStyleSheet
|
||||
*/
|
||||
_sheetRef: function(sheet) {
|
||||
if (this.refMap.has(sheet)) {
|
||||
return this.refMap.get(sheet);
|
||||
}
|
||||
let actor = StyleSheetActor(this, sheet);
|
||||
this.manage(actor);
|
||||
this.refMap.set(sheet, actor);
|
||||
|
||||
return actor;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the computed style for a node.
|
||||
*
|
||||
* @param NodeActor node
|
||||
* @param object options
|
||||
* `filter`: A string filter that affects the "matched" handling.
|
||||
* 'user': Include properties from user style sheets.
|
||||
* 'ua': Include properties from user and user-agent sheets.
|
||||
* Default value is 'ua'
|
||||
* `markMatched`: true if you want the 'matched' property to be added
|
||||
* when a computed property has been modified by a style included
|
||||
* by `filter`.
|
||||
* `onlyMatched`: true if unmatched properties shouldn't be included.
|
||||
*
|
||||
* @returns a JSON blob with the following form:
|
||||
* {
|
||||
* "property-name": {
|
||||
* value: "property-value",
|
||||
* priority: "!important" <optional>
|
||||
* matched: <true if there are matched selectors for this value>
|
||||
* },
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
getComputed: method(function(node, options) {
|
||||
let win = node.rawNode.ownerDocument.defaultView;
|
||||
let ret = Object.create(null);
|
||||
|
||||
this.cssLogic.sourceFilter = options.filter || CssLogic.FILTER.UA;
|
||||
this.cssLogic.highlight(node.rawNode);
|
||||
let computed = this.cssLogic._computedStyle;
|
||||
|
||||
Array.prototype.forEach.call(computed, name => {
|
||||
let matched = undefined;
|
||||
ret[name] = {
|
||||
value: computed.getPropertyValue(name),
|
||||
priority: computed.getPropertyPriority(name) || undefined
|
||||
};
|
||||
});
|
||||
|
||||
if (options.markMatched || options.onlyMatched) {
|
||||
let matched = this.cssLogic.hasMatchedSelectors(Object.keys(ret));
|
||||
for (let key in ret) {
|
||||
if (matched[key]) {
|
||||
ret[key].matched = options.markMatched ? true : undefined
|
||||
} else if (options.onlyMatched) {
|
||||
delete ret[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}, {
|
||||
request: {
|
||||
node: Arg(0, "domnode"),
|
||||
markMatched: Option(1, "boolean"),
|
||||
onlyMatched: Option(1, "boolean"),
|
||||
filter: Option(1, "string"),
|
||||
},
|
||||
response: {
|
||||
computed: RetVal("json")
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Get a list of selectors that match a given property for a node.
|
||||
*
|
||||
* @param NodeActor node
|
||||
* @param string property
|
||||
* @param object options
|
||||
* `filter`: A string filter that affects the "matched" handling.
|
||||
* 'user': Include properties from user style sheets.
|
||||
* 'ua': Include properties from user and user-agent sheets.
|
||||
* Default value is 'ua'
|
||||
*
|
||||
* @returns a JSON object with the following form:
|
||||
* {
|
||||
* // An ordered list of rules that apply
|
||||
* matched: [{
|
||||
* rule: <rule actorid>,
|
||||
* sourceText: <string>, // The source of the selector, relative
|
||||
* // to the node in question.
|
||||
* selector: <string>, // the selector ID that matched
|
||||
* value: <string>, // the value of the property
|
||||
* status: <int>,
|
||||
* // The status of the match - high numbers are better placed
|
||||
* // to provide styling information:
|
||||
* // 3: Best match, was used.
|
||||
* // 2: Matched, but was overridden.
|
||||
* // 1: Rule from a parent matched.
|
||||
* // 0: Unmatched (never returned in this API)
|
||||
* }, ...],
|
||||
*
|
||||
* // The full form of any domrule referenced.
|
||||
* rules: [ <domrule>, ... ], // The full form of any domrule referenced
|
||||
*
|
||||
* // The full form of any sheets referenced.
|
||||
* sheets: [ <domsheet>, ... ]
|
||||
* }
|
||||
*/
|
||||
getMatchedSelectors: method(function(node, property, options) {
|
||||
this.cssLogic.sourceFilter = options.filter || CssLogic.FILTER.UA;
|
||||
this.cssLogic.highlight(node.rawNode);
|
||||
|
||||
let walker = node.parent();
|
||||
|
||||
let rules = new Set;
|
||||
let sheets = new Set;
|
||||
|
||||
let matched = [];
|
||||
let propInfo = this.cssLogic.getPropertyInfo(property);
|
||||
for (let selectorInfo of propInfo.matchedSelectors) {
|
||||
let cssRule = selectorInfo.selector.cssRule;
|
||||
let domRule = cssRule.sourceElement || cssRule.domRule;
|
||||
|
||||
let rule = this._styleRef(domRule);
|
||||
rules.add(rule);
|
||||
|
||||
matched.push({
|
||||
rule: rule,
|
||||
sourceText: this.getSelectorSource(selectorInfo, node.rawNode),
|
||||
selector: selectorInfo.selector.text,
|
||||
value: selectorInfo.value,
|
||||
status: selectorInfo.status
|
||||
});
|
||||
}
|
||||
|
||||
this.expandSets(rules, sheets);
|
||||
|
||||
return {
|
||||
matched: matched,
|
||||
rules: [...rules],
|
||||
sheets: [...sheets],
|
||||
}
|
||||
}, {
|
||||
request: {
|
||||
node: Arg(0, "domnode"),
|
||||
property: Arg(1, "string"),
|
||||
filter: Option(2, "string")
|
||||
},
|
||||
response: RetVal(types.addDictType("matchedselectorresponse", {
|
||||
rules: "array:domstylerule",
|
||||
sheets: "array:domsheet",
|
||||
matched: "array:matchedselector"
|
||||
}))
|
||||
}),
|
||||
|
||||
// Get a selector source for a CssSelectorInfo relative to a given
|
||||
// node.
|
||||
getSelectorSource: function(selectorInfo, relativeTo) {
|
||||
let result = selectorInfo.selector.text;
|
||||
if (selectorInfo.elementStyle) {
|
||||
let source = selectorInfo.sourceElement;
|
||||
if (source === relativeTo) {
|
||||
result = "this";
|
||||
} else {
|
||||
result = CssLogic.getShortName(source);
|
||||
}
|
||||
result += ".style"
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the set of styles that apply to a given node.
|
||||
* @param NodeActor node
|
||||
* @param string property
|
||||
* @param object options
|
||||
* `filter`: A string filter that affects the "matched" handling.
|
||||
* 'user': Include properties from user style sheets.
|
||||
* 'ua': Include properties from user and user-agent sheets.
|
||||
* Default value is 'ua'
|
||||
* `inherited`: Include styles inherited from parent nodes.
|
||||
* `matchedSeletors`: Include an array of specific selectors that
|
||||
* caused this rule to match its node.
|
||||
*/
|
||||
getApplied: method(function(node, options) {
|
||||
let entries = [];
|
||||
|
||||
this.addElementRules(node.rawNode, undefined, options, entries);
|
||||
|
||||
if (options.inherited) {
|
||||
let parent = this.walker.parentNode(node);
|
||||
while (parent && parent.rawNode.nodeType != Ci.nsIDOMNode.DOCUMENT_NODE) {
|
||||
this.addElementRules(parent.rawNode, parent, options, entries);
|
||||
parent = this.walker.parentNode(parent);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.matchedSelectors) {
|
||||
for (let entry of entries) {
|
||||
if (entry.rule.type === ELEMENT_STYLE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let domRule = entry.rule.rawRule;
|
||||
let selectors = CssLogic.getSelectors(domRule);
|
||||
let element = entry.inherited ? entry.inherited.rawNode : node.rawNode;
|
||||
entry.matchedSelectors = [];
|
||||
for (let i = 0; i < selectors.length; i++) {
|
||||
if (DOMUtils.selectorMatchesElement(element, domRule, i)) {
|
||||
entry.matchedSelectors.push(selectors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
let rules = new Set;
|
||||
let sheets = new Set;
|
||||
entries.forEach(entry => rules.add(entry.rule));
|
||||
this.expandSets(rules, sheets);
|
||||
|
||||
return {
|
||||
entries: entries,
|
||||
rules: [...rules],
|
||||
sheets: [...sheets]
|
||||
}
|
||||
}, {
|
||||
request: {
|
||||
node: Arg(0, "domnode"),
|
||||
inherited: Option(1, "boolean"),
|
||||
matchedSelectors: Option(1, "boolean"),
|
||||
filter: Option(1, "string")
|
||||
},
|
||||
response: RetVal(types.addDictType("appliedStylesReturn", {
|
||||
entries: "array:appliedstyle",
|
||||
rules: "array:domstylerule",
|
||||
sheets: "array:domsheet"
|
||||
}))
|
||||
}),
|
||||
|
||||
_hasInheritedProps: function(style) {
|
||||
return Array.prototype.some.call(style, prop => {
|
||||
return DOMUtils.isInheritedProperty(prop);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper function for getApplied, adds all the rules from a given
|
||||
* element.
|
||||
*/
|
||||
addElementRules: function(element, inherited, options, rules)
|
||||
{
|
||||
let elementStyle = this._styleRef(element);
|
||||
|
||||
if (!inherited || this._hasInheritedProps(element.style)) {
|
||||
rules.push({
|
||||
rule: elementStyle,
|
||||
inherited: inherited,
|
||||
});
|
||||
}
|
||||
|
||||
// Get the styles that apply to the element.
|
||||
let domRules = DOMUtils.getCSSStyleRules(element);
|
||||
|
||||
// getCSSStyleRules returns ordered from least-specific to
|
||||
// most-specific.
|
||||
for (let i = domRules.Count() - 1; i >= 0; i--) {
|
||||
let domRule = domRules.GetElementAt(i);
|
||||
|
||||
let isSystem = !CssLogic.isContentStylesheet(domRule.parentStyleSheet);
|
||||
|
||||
if (isSystem && options.filter != CssLogic.FILTER.UA) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inherited) {
|
||||
// Don't include inherited rules if none of its properties
|
||||
// are inheritable.
|
||||
let hasInherited = Array.prototype.some.call(domRule.style, prop => {
|
||||
return DOMUtils.isInheritedProperty(prop);
|
||||
});
|
||||
if (!hasInherited) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let ruleActor = this._styleRef(domRule);
|
||||
rules.push({
|
||||
rule: ruleActor,
|
||||
inherited: inherited,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Expand Sets of rules and sheets to include all parent rules and sheets.
|
||||
*/
|
||||
expandSets: function(ruleSet, sheetSet) {
|
||||
// Sets include new items in their iteration
|
||||
for (let rule of ruleSet) {
|
||||
if (rule.rawRule.parentRule) {
|
||||
let parent = this._styleRef(rule.rawRule.parentRule);
|
||||
if (!ruleSet.has(parent)) {
|
||||
ruleSet.add(parent);
|
||||
}
|
||||
}
|
||||
if (rule.rawRule.parentStyleSheet) {
|
||||
let parent = this._sheetRef(rule.rawRule.parentStyleSheet);
|
||||
if (!sheetSet.has(parent)) {
|
||||
sheetSet.add(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let sheet of sheetSet) {
|
||||
if (sheet.rawSheet.parentStyleSheet) {
|
||||
let parent = this._sheetRef(sheet.rawSheet.parentStyleSheet);
|
||||
if (!sheetSet.has(parent)) {
|
||||
sheetSet.add(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
exports.PageStyleActor = PageStyleActor;
|
||||
|
||||
/**
|
||||
* Front object for the PageStyleActor
|
||||
*/
|
||||
var PageStyleFront = protocol.FrontClass(PageStyleActor, {
|
||||
initialize: function(conn, form, ctx, detail) {
|
||||
protocol.Front.prototype.initialize.call(this, conn, form, ctx, detail);
|
||||
this.inspector = this.parent();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
protocol.Front.prototype.destroy.call(this);
|
||||
},
|
||||
|
||||
get walker() {
|
||||
return this.inspector.walker;
|
||||
},
|
||||
|
||||
getMatchedSelectors: protocol.custom(function(node, property, options) {
|
||||
return this._getMatchedSelectors(node, property, options).then(ret => {
|
||||
return ret.matched;
|
||||
});
|
||||
}, {
|
||||
impl: "_getMatchedSelectors"
|
||||
}),
|
||||
|
||||
getApplied: protocol.custom(function(node, options={}) {
|
||||
return this._getApplied(node, options).then(ret => {
|
||||
return ret.entries;
|
||||
});
|
||||
}, {
|
||||
impl: "_getApplied"
|
||||
})
|
||||
});
|
||||
|
||||
/**
|
||||
* Actor representing an nsIDOMCSSStyleSheet.
|
||||
*/
|
||||
var StyleSheetActor = protocol.ActorClass({
|
||||
typeName: "domsheet",
|
||||
|
||||
initialize: function(pageStyle, sheet) {
|
||||
protocol.Front.prototype.initialize.call(this);
|
||||
this.pageStyle = pageStyle;
|
||||
this.rawSheet = sheet;
|
||||
},
|
||||
|
||||
get conn() this.pageStyle.conn,
|
||||
|
||||
form: function(detail) {
|
||||
if (detail === "actorid") {
|
||||
return this.actorID;
|
||||
}
|
||||
|
||||
return {
|
||||
actor: this.actorID,
|
||||
|
||||
// href stores the uri of the sheet
|
||||
href: this.rawSheet.href,
|
||||
|
||||
// nodeHref stores the URI of the document that
|
||||
// included the sheet.
|
||||
nodeHref: this.rawSheet.ownerNode ? this.rawSheet.ownerNode.ownerDocument.location.href : undefined,
|
||||
|
||||
system: !CssLogic.isContentStylesheet(this.rawSheet),
|
||||
disabled: this.rawSheet.disabled ? true : undefined
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Front for the StyleSheetActor.
|
||||
*/
|
||||
var StyleSheetFront = protocol.FrontClass(StyleSheetActor, {
|
||||
initialize: function(conn, form, ctx, detail) {
|
||||
protocol.Front.prototype.initialize.call(this, conn, form, ctx, detail);
|
||||
},
|
||||
|
||||
form: function(form, detail) {
|
||||
if (detail === "actorid") {
|
||||
this.actorID = form;
|
||||
return;
|
||||
}
|
||||
this.actorID = form.actorID;
|
||||
this._form = form;
|
||||
},
|
||||
|
||||
get href() this._form.href,
|
||||
get nodeHref() this._form.nodeHref,
|
||||
get disabled() !!this._form.disabled,
|
||||
get isSystem() this._form.system
|
||||
});
|
||||
|
||||
|
||||
// Predeclare the domstylerule actor type
|
||||
types.addActorType("domstylerule");
|
||||
|
||||
/**
|
||||
* An actor that represents a CSS style object on the protocol.
|
||||
*
|
||||
* We slightly flatten the CSSOM for this actor, it represents
|
||||
* both the CSSRule and CSSStyle objects in one actor. For nodes
|
||||
* (which have a CSSStyle but no CSSRule) we create a StyleRuleActor
|
||||
* with a special rule type (100).
|
||||
*/
|
||||
var StyleRuleActor = protocol.ActorClass({
|
||||
typeName: "domstylerule",
|
||||
initialize: function(pageStyle, item) {
|
||||
protocol.Actor.prototype.initialize.call(this, null);
|
||||
this.pageStyle = pageStyle;
|
||||
this.rawStyle = item.style;
|
||||
|
||||
if (item instanceof (Ci.nsIDOMCSSRule)) {
|
||||
this.type = item.type;
|
||||
this.rawRule = item;
|
||||
if (this.rawRule instanceof Ci.nsIDOMCSSStyleRule && this.rawRule.parentStyleSheet) {
|
||||
this.line = DOMUtils.getRuleLine(this.rawRule);
|
||||
}
|
||||
} else {
|
||||
// Fake a rule
|
||||
this.type = ELEMENT_STYLE;
|
||||
this.rawNode = item;
|
||||
this.rawRule = {
|
||||
style: item.style,
|
||||
toString: function() "[element rule " + this.style + "]"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
get conn() this.pageStyle.conn,
|
||||
|
||||
// Objects returned by this actor are owned by the PageStyleActor
|
||||
// to which this rule belongs.
|
||||
get marshallPool() this.pageStyle,
|
||||
|
||||
toString: function() "[StyleRuleActor for " + this.rawRule + "]",
|
||||
|
||||
form: function(detail) {
|
||||
if (detail === "actorid") {
|
||||
return this.actorID;
|
||||
}
|
||||
|
||||
let form = {
|
||||
actor: this.actorID,
|
||||
type: this.type,
|
||||
line: this.line || undefined,
|
||||
};
|
||||
|
||||
if (this.rawRule.parentRule) {
|
||||
form.parentRule = this.pageStyle._styleRef(this.rawRule.parentRule).actorID;
|
||||
}
|
||||
if (this.rawRule.parentStyleSheet) {
|
||||
form.parentStyleSheet = this.pageStyle._sheetRef(this.rawRule.parentStyleSheet).actorID;
|
||||
}
|
||||
|
||||
switch (this.type) {
|
||||
case Ci.nsIDOMCSSRule.STYLE_RULE:
|
||||
form.selectors = CssLogic.getSelectors(this.rawRule);
|
||||
form.cssText = this.rawStyle.cssText || "";
|
||||
break;
|
||||
case ELEMENT_STYLE:
|
||||
// Elements don't have a parent stylesheet, and therefore
|
||||
// don't have an associated URI. Provide a URI for
|
||||
// those.
|
||||
form.href = this.rawNode.ownerDocument.location.href;
|
||||
form.cssText = this.rawStyle.cssText || "";
|
||||
break;
|
||||
case Ci.nsIDOMCSSRule.CHARSET_RULE:
|
||||
form.encoding = this.rawRule.encoding;
|
||||
break;
|
||||
case Ci.nsIDOMCSSRule.IMPORT_RULE:
|
||||
form.href = this.rawRule.href;
|
||||
break;
|
||||
case Ci.nsIDOMCSSRule.MEDIA_RULE:
|
||||
form.media = [];
|
||||
for (let i = 0, n = this.rawRule.media.length; i < n; i++) {
|
||||
form.media.push(this.rawRule.media.item(i));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return form;
|
||||
},
|
||||
|
||||
/**
|
||||
* Modify a rule's properties. Passed an array of modifications:
|
||||
* {
|
||||
* type: "set",
|
||||
* name: <string>,
|
||||
* value: <string>,
|
||||
* priority: <optional string>
|
||||
* }
|
||||
* or
|
||||
* {
|
||||
* type: "remove",
|
||||
* name: <string>,
|
||||
* }
|
||||
*
|
||||
* @returns the rule with updated properties
|
||||
*/
|
||||
modifyProperties: method(function(modifications) {
|
||||
for (let mod of modifications) {
|
||||
if (mod.type === "set") {
|
||||
this.rawStyle.setProperty(mod.name, mod.value, mod.priority || "");
|
||||
} else if (mod.type === "remove") {
|
||||
this.rawStyle.removeProperty(mod.name);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}, {
|
||||
request: { modifications: Arg(0, "array:json") },
|
||||
response: { rule: RetVal("domstylerule") }
|
||||
})
|
||||
});
|
||||
|
||||
/**
|
||||
* Front for the StyleRule actor.
|
||||
*/
|
||||
var StyleRuleFront = protocol.FrontClass(StyleRuleActor, {
|
||||
initialize: function(client, form, ctx, detail) {
|
||||
protocol.Front.prototype.initialize.call(this, client, form, ctx, detail);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
protocol.Front.prototype.destroy.call(this);
|
||||
},
|
||||
|
||||
form: function(form, detail) {
|
||||
if (detail === "actorid") {
|
||||
this.actorID = form;
|
||||
return;
|
||||
}
|
||||
this.actorID = form.actor;
|
||||
this._form = form;
|
||||
if (this._mediaText) {
|
||||
this._mediaText = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Return a new RuleModificationList for this node.
|
||||
*/
|
||||
startModifyingProperties: function() {
|
||||
return new RuleModificationList(this);
|
||||
},
|
||||
|
||||
get type() this._form.type,
|
||||
get line() this._form.line || -1,
|
||||
get cssText() {
|
||||
return this._form.cssText;
|
||||
},
|
||||
get selectors() {
|
||||
return this._form.selectors;
|
||||
},
|
||||
get media() {
|
||||
return this._form.media;
|
||||
},
|
||||
get mediaText() {
|
||||
if (!this._form.media) {
|
||||
return null;
|
||||
}
|
||||
if (this._mediaText) {
|
||||
return this._mediaText;
|
||||
}
|
||||
this._mediaText = this.media.join(", ");
|
||||
return this._mediaText;
|
||||
},
|
||||
|
||||
get parentRule() {
|
||||
return this.conn.getActor(this._form.parentRule);
|
||||
},
|
||||
|
||||
get parentStyleSheet() {
|
||||
return this.conn.getActor(this._form.parentStyleSheet);
|
||||
},
|
||||
|
||||
get element() {
|
||||
return this.conn.getActor(this._form.element);
|
||||
},
|
||||
|
||||
get href() {
|
||||
if (this._form.href) {
|
||||
return this._form.href;
|
||||
}
|
||||
let sheet = this.parentStyleSheet;
|
||||
return sheet.href || sheet.nodeHref;
|
||||
},
|
||||
|
||||
// Only used for testing, please keep it that way.
|
||||
_rawStyle: function() {
|
||||
if (!this.conn._transport._serverConnection) {
|
||||
console.warn("Tried to use rawNode on a remote connection.");
|
||||
return null;
|
||||
}
|
||||
let actor = this.conn._transport._serverConnection.getActor(this.actorID);
|
||||
if (!actor) {
|
||||
return null;
|
||||
}
|
||||
return actor.rawStyle;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Convenience API for building a list of attribute modifications
|
||||
* for the `modifyAttributes` request.
|
||||
*/
|
||||
var RuleModificationList = Class({
|
||||
initialize: function(rule) {
|
||||
this.rule = rule;
|
||||
this.modifications = [];
|
||||
},
|
||||
|
||||
apply: function() {
|
||||
return this.rule.modifyProperties(this.modifications);
|
||||
},
|
||||
setProperty: function(name, value, priority) {
|
||||
this.modifications.push({
|
||||
type: "set",
|
||||
name: name,
|
||||
value: value,
|
||||
priority: priority
|
||||
});
|
||||
},
|
||||
removeProperty: function(name) {
|
||||
this.modifications.push({
|
||||
type: "remove",
|
||||
name: name
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -14,6 +14,8 @@ include $(DEPTH)/config/autoconf.mk
|
|||
MOCHITEST_CHROME_FILES = \
|
||||
inspector-helpers.js \
|
||||
inspector-traversal-data.html \
|
||||
inspector-styles-data.html \
|
||||
inspector-styles-data.css \
|
||||
test_inspector-changeattrs.html \
|
||||
test_inspector-changevalue.html \
|
||||
test_inspector-hide.html \
|
||||
|
@ -28,6 +30,10 @@ MOCHITEST_CHROME_FILES = \
|
|||
test_inspector-retain.html \
|
||||
test_inspector-pseudoclass-lock.html \
|
||||
test_inspector-traversal.html \
|
||||
test_styles-applied.html \
|
||||
test_styles-computed.html \
|
||||
test_styles-matched.html \
|
||||
test_styles-modify.html \
|
||||
test_unsafeDereference.html \
|
||||
nonchrome_unsafeDereference.html \
|
||||
$(NULL)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
.external-rule {
|
||||
cursor: crosshair;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<html>
|
||||
<script>
|
||||
window.onload = () => {
|
||||
window.opener.postMessage('ready', '*')
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.inheritable-rule {
|
||||
font-size: 15px;
|
||||
}
|
||||
.uninheritable-rule {
|
||||
background-color: #f06;
|
||||
}
|
||||
@media screen {
|
||||
#mediaqueried {
|
||||
background-color: #f06;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<link type="text/css" rel="stylesheet" href="inspector-styles-data.css"></link>
|
||||
<body>
|
||||
<h1>Style Actor Tests</h1>
|
||||
<!-- Inheritance checks -->
|
||||
<div id="inheritable-rule-uninheritable-style" class="inheritable-rule" style="background-color: purple">
|
||||
<div id="inheritable-rule-inheritable-style" class="inheritable-rule" style="color: blue">
|
||||
<div id="uninheritable-rule-uninheritable-style" class="uninheritable-rule" style="background-color: green">
|
||||
<div id="uninheritable-rule-inheritable-style" class="uninheritable-rule" style="color: red">
|
||||
<div id="test-node">
|
||||
Here is the test node.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Computed checks -->
|
||||
<div id="computed-parent" class="external-rule inheritable-rule uninheritable-rule" style="color: red;">
|
||||
<div id="computed-test-node" class="external-rule">
|
||||
Here is the test node.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Matched checks -->
|
||||
<div id="matched-parent" class="external-rule inheritable-rule uninheritable-rule" style="color: red;">
|
||||
<div id="matched-test-node" style="font-size: 10px" class="external-rule">
|
||||
Here is the test node.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="mediaqueried">
|
||||
Screen mediaqueried.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -14,7 +14,7 @@
|
|||
body.appendChild(iframe);
|
||||
}
|
||||
</script>
|
||||
<body>
|
||||
<body style="background-color:white">
|
||||
<h1>Inspector Actor Tests</h1>
|
||||
<span id="longstring">longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong</span>
|
||||
<span id="shortstring">short</span>
|
||||
|
@ -51,4 +51,4 @@
|
|||
<div id="longlist-sibling-firstchild"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug </title>
|
||||
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
<script type="application/javascript;version=1.8" src="inspector-helpers.js"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
Components.utils.import("resource://gre/modules/devtools/Loader.jsm");
|
||||
|
||||
const promise = devtools.require("sdk/core/promise");
|
||||
const inspector = devtools.require("devtools/server/actors/inspector");
|
||||
|
||||
window.onload = function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
var gWalker = null;
|
||||
var gStyles = null;
|
||||
var gClient = null;
|
||||
|
||||
addTest(function setup() {
|
||||
let url = document.getElementById("inspectorContent").href;
|
||||
attachURL(url, function(err, client, tab, doc) {
|
||||
gInspectee = doc;
|
||||
let {InspectorFront} = devtools.require("devtools/server/actors/inspector");
|
||||
let inspector = InspectorFront(client, tab);
|
||||
promiseDone(inspector.getWalker().then(walker => {
|
||||
ok(walker, "getWalker() should return an actor.");
|
||||
gClient = client;
|
||||
gWalker = walker;
|
||||
return inspector.getPageStyle();
|
||||
}).then(styles => {
|
||||
gStyles = styles;
|
||||
}).then(runNextTest));
|
||||
});
|
||||
});
|
||||
|
||||
addTest(function inheritedUserStyles() {
|
||||
let node = node;
|
||||
promiseDone(gWalker.querySelector(gWalker.rootNode, "#test-node").then(node => {
|
||||
return gStyles.getApplied(node, { inherited: true, filter: "user" });
|
||||
}).then(applied => {
|
||||
ok(!applied[0].inherited, "Entry 0 should be uninherited");
|
||||
is(applied[0].rule.type, 100, "Entry 0 should be an element style");
|
||||
ok(!!applied[0].rule.href, "Element styles should have a URL");
|
||||
is(applied[0].rule.cssText, "", "Entry 0 should be an empty style");
|
||||
|
||||
is(applied[1].inherited.id, "uninheritable-rule-inheritable-style",
|
||||
"Entry 1 should be inherited from the parent");
|
||||
is(applied[1].rule.type, 100, "Entry 1 should be an element style");
|
||||
is(applied[1].rule.cssText, "color: red;", "Entry 1 should have the expected cssText");
|
||||
|
||||
is(applied[2].inherited.id, "inheritable-rule-inheritable-style",
|
||||
"Entry 2 should be inherited from the parent's parent");
|
||||
is(applied[2].rule.type, 100, "Entry 2 should be an element style");
|
||||
is(applied[2].rule.cssText, "color: blue;", "Entry 2 should have the expected cssText");
|
||||
|
||||
is(applied[3].inherited.id, "inheritable-rule-inheritable-style",
|
||||
"Entry 3 should be inherited from the parent's parent");
|
||||
is(applied[3].rule.type, 1, "Entry 3 should be a rule style");
|
||||
is(applied[3].rule.cssText, "font-size: 15px;", "Entry 3 should have the expected cssText");
|
||||
ok(!applied[3].matchedSelectors, "Shouldn't get matchedSelectors with this request.");
|
||||
|
||||
is(applied[4].inherited.id, "inheritable-rule-uninheritable-style",
|
||||
"Entry 4 should be inherited from the parent's parent");
|
||||
is(applied[4].rule.type, 1, "Entry 4 should be an rule style");
|
||||
is(applied[4].rule.cssText, "font-size: 15px;", "Entry 4 should have the expected cssText");
|
||||
ok(!applied[4].matchedSelectors, "Shouldn't get matchedSelectors with this request.");
|
||||
|
||||
is(applied.length, 5, "Should have 5 rules.");
|
||||
}).then(runNextTest));
|
||||
});
|
||||
|
||||
addTest(function inheritedSystemStyles() {
|
||||
let node = node;
|
||||
promiseDone(gWalker.querySelector(gWalker.rootNode, "#test-node").then(node => {
|
||||
return gStyles.getApplied(node, { inherited: true, filter: "ua" });
|
||||
}).then(applied => {
|
||||
// If our system stylesheets are prone to churn, this might be a fragile
|
||||
// test. If you're here because of that I apologize, file a bug
|
||||
// and we can find a different way to test.
|
||||
|
||||
ok(!applied[1].inherited, "Entry 1 should not be inherited");
|
||||
ok(!applied[1].rule.parentStyleSheet.system, "Entry 1 should be a system style");
|
||||
is(applied[1].rule.type, 1, "Entry 1 should be a rule style");
|
||||
|
||||
is(applied.length, 7, "Should have 7 rules.");
|
||||
}).then(runNextTest));
|
||||
});
|
||||
|
||||
addTest(function noInheritedStyles() {
|
||||
let node = node;
|
||||
promiseDone(gWalker.querySelector(gWalker.rootNode, "#test-node").then(node => {
|
||||
return gStyles.getApplied(node, { inherited: false, filter: "user" });
|
||||
}).then(applied => {
|
||||
ok(!applied[0].inherited, "Entry 0 should be uninherited");
|
||||
is(applied[0].rule.type, 100, "Entry 0 should be an element style");
|
||||
is(applied[0].rule.cssText, "", "Entry 0 should be an empty style");
|
||||
is(applied.length, 1, "Should have 1 rule.");
|
||||
}).then(runNextTest));
|
||||
});
|
||||
|
||||
addTest(function matchedSelectors() {
|
||||
promiseDone(gWalker.querySelector(gWalker.rootNode, "#test-node").then(node => {
|
||||
return gStyles.getApplied(node, {
|
||||
inherited: true, filter: "user", matchedSelectors: true
|
||||
});
|
||||
}).then(applied => {
|
||||
is(applied[3].matchedSelectors[0], ".inheritable-rule", "Entry 3 should have a matched selector");
|
||||
is(applied[4].matchedSelectors[0], ".inheritable-rule", "Entry 4 should have a matched selector");
|
||||
}).then(runNextTest));
|
||||
});
|
||||
|
||||
addTest(function testMediaQuery() {
|
||||
let node = node;
|
||||
promiseDone(gWalker.querySelector(gWalker.rootNode, "#mediaqueried").then(node => {
|
||||
return gStyles.getApplied(node, {
|
||||
inherited: false, filter: "user", matchedSelectors: true
|
||||
});
|
||||
}).then(applied => {
|
||||
is(applied[1].rule.type, 1, "Entry 1 is a rule style");
|
||||
is(applied[1].rule.parentRule.type, 4, "Entry 1's parent rule is a media rule");
|
||||
is(applied[1].rule.parentRule.media[0], "screen", "Entry 1's parent rule has the expected medium");
|
||||
}).then(runNextTest));
|
||||
});
|
||||
|
||||
addTest(function cleanup() {
|
||||
delete gStyles;
|
||||
delete gWalker;
|
||||
delete gClient;
|
||||
runNextTest();
|
||||
});
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a>
|
||||
<a id="inspectorContent" target="_blank" href="inspector-styles-data.html">Test Document</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,142 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug </title>
|
||||
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
<script type="application/javascript;version=1.8" src="inspector-helpers.js"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
Components.utils.import("resource://gre/modules/devtools/Loader.jsm");
|
||||
|
||||
const promise = devtools.require("sdk/core/promise");
|
||||
const inspector = devtools.require("devtools/server/actors/inspector");
|
||||
|
||||
window.onload = function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
var gWalker = null;
|
||||
var gStyles = null;
|
||||
var gClient = null;
|
||||
|
||||
addTest(function setup() {
|
||||
let url = document.getElementById("inspectorContent").href;
|
||||
attachURL(url, function(err, client, tab, doc) {
|
||||
gInspectee = doc;
|
||||
let {InspectorFront} = devtools.require("devtools/server/actors/inspector");
|
||||
let inspector = InspectorFront(client, tab);
|
||||
promiseDone(inspector.getWalker().then(walker => {
|
||||
ok(walker, "getWalker() should return an actor.");
|
||||
gClient = client;
|
||||
gWalker = walker;
|
||||
return inspector.getPageStyle();
|
||||
}).then(styles => {
|
||||
gStyles = styles;
|
||||
}).then(runNextTest));
|
||||
});
|
||||
});
|
||||
|
||||
addTest(function testComputed() {
|
||||
let localNode = gInspectee.querySelector("#computed-test-node");
|
||||
let elementStyle = null;
|
||||
promiseDone(gWalker.querySelector(gWalker.rootNode, "#computed-test-node").then(node => {
|
||||
return gStyles.getComputed(node, {});
|
||||
}).then(computed => {
|
||||
// Test a smattering of properties that include some system-defined
|
||||
// props, some props that were defined in this node's stylesheet,
|
||||
// and some default props.
|
||||
is(computed["white-space"].value, "normal", "Default value should appear");
|
||||
is(computed["display"].value, "block", "System stylesheet item should appear");
|
||||
is(computed["cursor"].value, "crosshair", "Included stylesheet rule should appear");
|
||||
is(computed["color"].value, "rgb(255, 0, 0)", "Inherited style attribute should appear");
|
||||
is(computed["font-size"].value, "15px", "Inherited inline rule should appear");
|
||||
|
||||
// We didn't request markMatched, so these shouldn't be set
|
||||
ok(!computed["cursor"].matched, "Didn't ask for matched, shouldn't get it");
|
||||
ok(!computed["color"].matched, "Didn't ask for matched, shouldn't get it");
|
||||
ok(!computed["font-size"].matched, "Didn't ask for matched, shouldn't get it");
|
||||
}).then(runNextTest));
|
||||
});
|
||||
|
||||
addTest(function testComputedUserMatched() {
|
||||
let localNode = gInspectee.querySelector("#computed-test-node");
|
||||
let elementStyle = null;
|
||||
promiseDone(gWalker.querySelector(gWalker.rootNode, "#computed-test-node").then(node => {
|
||||
return gStyles.getComputed(node, { filter: "user", markMatched: true });
|
||||
}).then(computed => {
|
||||
ok(!computed["white-space"].matched, "Default style shouldn't match");
|
||||
ok(!computed["display"].matched, "Only user styles should match");
|
||||
ok(computed["cursor"].matched, "Asked for matched, should get it");
|
||||
ok(computed["color"].matched, "Asked for matched, should get it");
|
||||
ok(computed["font-size"].matched, "Asked for matched, should get it");
|
||||
}).then(runNextTest));
|
||||
});
|
||||
|
||||
addTest(function testComputedSystemMatched() {
|
||||
let localNode = gInspectee.querySelector("#computed-test-node");
|
||||
let elementStyle = null;
|
||||
promiseDone(gWalker.querySelector(gWalker.rootNode, "#computed-test-node").then(node => {
|
||||
return gStyles.getComputed(node, { filter: "ua", markMatched: true });
|
||||
}).then(computed => {
|
||||
ok(!computed["white-space"].matched, "Default style shouldn't match");
|
||||
ok(computed["display"].matched, "System stylesheets should match");
|
||||
ok(computed["cursor"].matched, "Asked for matched, should get it");
|
||||
ok(computed["color"].matched, "Asked for matched, should get it");
|
||||
ok(computed["font-size"].matched, "Asked for matched, should get it");
|
||||
}).then(runNextTest));
|
||||
});
|
||||
|
||||
addTest(function testComputedUserOnlyMatched() {
|
||||
let localNode = gInspectee.querySelector("#computed-test-node");
|
||||
let elementStyle = null;
|
||||
promiseDone(gWalker.querySelector(gWalker.rootNode, "#computed-test-node").then(node => {
|
||||
return gStyles.getComputed(node, { filter: "user", onlyMatched: true });
|
||||
}).then(computed => {
|
||||
ok(!("white-space" in computed), "Default style shouldn't exist");
|
||||
ok(!("display" in computed), "System stylesheets shouldn't exist");
|
||||
ok(("cursor" in computed), "User items should exist.");
|
||||
ok(("color" in computed), "User items should exist.");
|
||||
ok(("font-size" in computed), "User items should exist.");
|
||||
}).then(runNextTest));
|
||||
});
|
||||
|
||||
addTest(function testComputedSystemOnlyMatched() {
|
||||
let localNode = gInspectee.querySelector("#computed-test-node");
|
||||
let elementStyle = null;
|
||||
promiseDone(gWalker.querySelector(gWalker.rootNode, "#computed-test-node").then(node => {
|
||||
return gStyles.getComputed(node, { filter: "ua", onlyMatched: true });
|
||||
}).then(computed => {
|
||||
ok(!("white-space" in computed), "Default style shouldn't exist");
|
||||
ok(("display" in computed), "System stylesheets should exist");
|
||||
ok(("cursor" in computed), "User items should exist.");
|
||||
ok(("color" in computed), "User items should exist.");
|
||||
ok(("font-size" in computed), "User items should exist.");
|
||||
}).then(runNextTest));
|
||||
});
|
||||
|
||||
addTest(function cleanup() {
|
||||
delete gStyles;
|
||||
delete gWalker;
|
||||
delete gClient;
|
||||
runNextTest();
|
||||
});
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a>
|
||||
<a id="inspectorContent" target="_blank" href="inspector-styles-data.html">Test Document</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,101 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug </title>
|
||||
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
<script type="application/javascript;version=1.8" src="inspector-helpers.js"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
Components.utils.import("resource://gre/modules/devtools/Loader.jsm");
|
||||
|
||||
const promise = devtools.require("sdk/core/promise");
|
||||
const inspector = devtools.require("devtools/server/actors/inspector");
|
||||
const {CssLogic} = devtools.require("devtools/styleinspector/css-logic");
|
||||
|
||||
window.onload = function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
var gWalker = null;
|
||||
var gStyles = null;
|
||||
var gClient = null;
|
||||
|
||||
addTest(function setup() {
|
||||
let url = document.getElementById("inspectorContent").href;
|
||||
attachURL(url, function(err, client, tab, doc) {
|
||||
gInspectee = doc;
|
||||
let {InspectorFront} = devtools.require("devtools/server/actors/inspector");
|
||||
let inspector = InspectorFront(client, tab);
|
||||
promiseDone(inspector.getWalker().then(walker => {
|
||||
ok(walker, "getWalker() should return an actor.");
|
||||
gClient = client;
|
||||
gWalker = walker;
|
||||
return inspector.getPageStyle();
|
||||
}).then(styles => {
|
||||
gStyles = styles;
|
||||
}).then(runNextTest));
|
||||
});
|
||||
});
|
||||
|
||||
addTest(function testMatchedStyles() {
|
||||
promiseDone(gWalker.querySelector(gWalker.rootNode, "#matched-test-node").then(node => {
|
||||
return gStyles.getMatchedSelectors(node, "font-size", {});
|
||||
}).then(matched => {
|
||||
is(matched[0].sourceText, "this.style", "First match comes from the element style");
|
||||
is(matched[0].selector, "@element.style", "Element style has a special selector");
|
||||
is(matched[0].value, "10px", "First match has the expected value");
|
||||
is(matched[0].status, CssLogic.STATUS.BEST, "First match is the best match")
|
||||
is(matched[0].rule.type, 100, "First match is an element style");
|
||||
is(matched[0].rule.href, gInspectee.defaultView.location.href, "Node style comes from this document")
|
||||
|
||||
is(matched[1].sourceText, ".inheritable-rule", "Second match comes from a rule");
|
||||
is(matched[1].selector, ".inheritable-rule", "Second style has a selector");
|
||||
is(matched[1].value, "15px", "Second match has the expected value");
|
||||
is(matched[1].status, CssLogic.STATUS.PARENT_MATCH, "Second match is from the parent")
|
||||
is(matched[1].rule.parentStyleSheet.href, null, "Inline stylesheet shouldn't have an href");
|
||||
is(matched[1].rule.parentStyleSheet.nodeHref, gInspectee.defaultView.location.href, "Inline stylesheet's nodeHref should match the current document");
|
||||
ok(!matched[1].rule.parentStyleSheet.system, "Inline stylesheet shouldn't be a system stylesheet.");
|
||||
}).then(runNextTest));
|
||||
});
|
||||
|
||||
addTest(function testSystemStyles() {
|
||||
let testNode = null;
|
||||
|
||||
promiseDone(gWalker.querySelector(gWalker.rootNode, "#matched-test-node").then(node => {
|
||||
testNode = node;
|
||||
return gStyles.getMatchedSelectors(testNode, "display", { filter: "user" });
|
||||
}).then(matched => {
|
||||
is(matched.length, 0, "No user selectors apply to this rule.");
|
||||
return gStyles.getMatchedSelectors(testNode, "display", { filter: "ua" });
|
||||
}).then(matched => {
|
||||
is(matched[0].selector, "div", "Should match system div selector");
|
||||
is(matched[0].value, "block");
|
||||
}).then(runNextTest));
|
||||
});
|
||||
|
||||
addTest(function cleanup() {
|
||||
delete gStyles;
|
||||
delete gWalker;
|
||||
delete gClient;
|
||||
runNextTest();
|
||||
});
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a>
|
||||
<a id="inspectorContent" target="_blank" href="inspector-styles-data.html">Test Document</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,103 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug </title>
|
||||
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
<script type="application/javascript;version=1.8" src="inspector-helpers.js"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
Components.utils.import("resource://gre/modules/devtools/Loader.jsm");
|
||||
|
||||
const promise = devtools.require("sdk/core/promise");
|
||||
const inspector = devtools.require("devtools/server/actors/inspector");
|
||||
|
||||
window.onload = function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
var gWalker = null;
|
||||
var gStyles = null;
|
||||
var gClient = null;
|
||||
|
||||
addTest(function setup() {
|
||||
let url = document.getElementById("inspectorContent").href;
|
||||
attachURL(url, function(err, client, tab, doc) {
|
||||
gInspectee = doc;
|
||||
let {InspectorFront} = devtools.require("devtools/server/actors/inspector");
|
||||
let inspector = InspectorFront(client, tab);
|
||||
promiseDone(inspector.getWalker().then(walker => {
|
||||
ok(walker, "getWalker() should return an actor.");
|
||||
gClient = client;
|
||||
gWalker = walker;
|
||||
return inspector.getPageStyle();
|
||||
}).then(styles => {
|
||||
gStyles = styles;
|
||||
}).then(runNextTest));
|
||||
});
|
||||
});
|
||||
|
||||
addTest(function modifyProperties() {
|
||||
let localNode = gInspectee.querySelector("#inheritable-rule-inheritable-style");
|
||||
let elementStyle = null;
|
||||
promiseDone(gWalker.querySelector(gWalker.rootNode, "#inheritable-rule-inheritable-style").then(node => {
|
||||
return gStyles.getApplied(node, { inherited: false, filter: "user" });
|
||||
}).then(applied => {
|
||||
elementStyle = applied[0].rule;
|
||||
is(elementStyle.cssText, localNode.style.cssText, "Got expected css text");
|
||||
|
||||
// Will start with "color:blue"
|
||||
let changes = elementStyle.startModifyingProperties();
|
||||
|
||||
// Change an existing property...
|
||||
changes.setProperty("color", "black");
|
||||
// Create a new property
|
||||
changes.setProperty("background-color", "green");
|
||||
|
||||
// Create a new property and then change it immediately.
|
||||
changes.setProperty("border", "1px solid black");
|
||||
changes.setProperty("border", "2px solid black");
|
||||
|
||||
return changes.apply();
|
||||
}).then(() => {
|
||||
is(elementStyle.cssText, "color: black; background-color: green; border: 2px solid black;", "Should have expected cssText");
|
||||
is(elementStyle.cssText, localNode.style.cssText, "Local node and style front match.");
|
||||
|
||||
// Remove all the properties
|
||||
let changes = elementStyle.startModifyingProperties();
|
||||
changes.removeProperty("color");
|
||||
changes.removeProperty("background-color");
|
||||
changes.removeProperty("border");
|
||||
|
||||
return changes.apply();
|
||||
}).then(() => {
|
||||
is(elementStyle.cssText, "", "Should have expected cssText");
|
||||
is(elementStyle.cssText, localNode.style.cssText, "Local node and style front match.");
|
||||
}).then(runNextTest));
|
||||
});
|
||||
|
||||
addTest(function cleanup() {
|
||||
delete gStyles;
|
||||
delete gWalker;
|
||||
delete gClient;
|
||||
runNextTest();
|
||||
});
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a>
|
||||
<a id="inspectorContent" target="_blank" href="inspector-styles-data.html">Test Document</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -63,8 +63,8 @@ exports.CssLogic = CssLogic;
|
|||
* Special values for filter, in addition to an href these values can be used
|
||||
*/
|
||||
CssLogic.FILTER = {
|
||||
ALL: "all", // show properties from all user style sheets.
|
||||
UA: "ua", // ALL, plus user-agent (i.e. browser) style sheets
|
||||
USER: "user", // show properties for all user style sheets.
|
||||
UA: "ua", // USER, plus user-agent (i.e. browser) style sheets
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -112,7 +112,7 @@ CssLogic.prototype = {
|
|||
_computedStyle: null,
|
||||
|
||||
// Source filter. Only display properties coming from the given source
|
||||
_sourceFilter: CssLogic.FILTER.ALL,
|
||||
_sourceFilter: CssLogic.FILTER.USER,
|
||||
|
||||
// Used for tracking unique CssSheet/CssRule/CssSelector objects, in a run of
|
||||
// processMatchedSelectors().
|
||||
|
@ -448,7 +448,7 @@ CssLogic.prototype = {
|
|||
this._passId++;
|
||||
this._matchedSelectors.forEach(function(aValue) {
|
||||
aCallback.call(aScope, aValue[0], aValue[1]);
|
||||
aValue[0]._cssRule._passId = this._passId;
|
||||
aValue[0].cssRule._passId = this._passId;
|
||||
}, this);
|
||||
}
|
||||
return;
|
||||
|
@ -468,7 +468,7 @@ CssLogic.prototype = {
|
|||
rule.selectors.forEach(function (aSelector) {
|
||||
if (aSelector._matchId !== this._matchId &&
|
||||
(aSelector.elementStyle ||
|
||||
this.selectorMatchesElement(rule._domRule, aSelector.selectorIndex))) {
|
||||
this.selectorMatchesElement(rule.domRule, aSelector.selectorIndex))) {
|
||||
|
||||
aSelector._matchId = this._matchId;
|
||||
this._matchedSelectors.push([ aSelector, status ]);
|
||||
|
@ -590,7 +590,7 @@ CssLogic.prototype = {
|
|||
sheet._passId = this._passId;
|
||||
}
|
||||
|
||||
if (filter === CssLogic.FILTER.ALL && !sheet.contentSheet) {
|
||||
if (filter === CssLogic.FILTER.USER && !sheet.contentSheet) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -988,10 +988,10 @@ CssSheet.prototype = {
|
|||
this._sheetAllowed = true;
|
||||
|
||||
let filter = this._cssLogic.sourceFilter;
|
||||
if (filter === CssLogic.FILTER.ALL && !this.contentSheet) {
|
||||
if (filter === CssLogic.FILTER.USER && !this.contentSheet) {
|
||||
this._sheetAllowed = false;
|
||||
}
|
||||
if (filter !== CssLogic.FILTER.ALL && filter !== CssLogic.FILTER.UA) {
|
||||
if (filter !== CssLogic.FILTER.USER && filter !== CssLogic.FILTER.UA) {
|
||||
this._sheetAllowed = (filter === this.href);
|
||||
}
|
||||
|
||||
|
@ -1030,7 +1030,7 @@ CssSheet.prototype = {
|
|||
if (cacheId in this._rules) {
|
||||
for (let i = 0, rulesLen = this._rules[cacheId].length; i < rulesLen; i++) {
|
||||
rule = this._rules[cacheId][i];
|
||||
if (rule._domRule === aDomRule) {
|
||||
if (rule.domRule === aDomRule) {
|
||||
ruleFound = true;
|
||||
break;
|
||||
}
|
||||
|
@ -1134,7 +1134,7 @@ CssSheet.prototype = {
|
|||
function CssRule(aCssSheet, aDomRule, aElement)
|
||||
{
|
||||
this._cssSheet = aCssSheet;
|
||||
this._domRule = aDomRule;
|
||||
this.domRule = aDomRule;
|
||||
|
||||
let parentRule = aDomRule.parentRule;
|
||||
if (parentRule && parentRule.type == Ci.nsIDOMCSSRule.MEDIA_RULE) {
|
||||
|
@ -1142,9 +1142,9 @@ function CssRule(aCssSheet, aDomRule, aElement)
|
|||
}
|
||||
|
||||
if (this._cssSheet) {
|
||||
// parse _domRule.selectorText on call to this.selectors
|
||||
// parse domRule.selectorText on call to this.selectors
|
||||
this._selectors = null;
|
||||
this.line = domUtils.getRuleLine(this._domRule);
|
||||
this.line = domUtils.getRuleLine(this.domRule);
|
||||
this.source = this._cssSheet.shortSource + ":" + this.line;
|
||||
if (this.mediaText) {
|
||||
this.source += " @media " + this.mediaText;
|
||||
|
@ -1202,7 +1202,7 @@ CssRule.prototype = {
|
|||
*/
|
||||
getPropertyValue: function(aProperty)
|
||||
{
|
||||
return this._domRule.style.getPropertyValue(aProperty);
|
||||
return this.domRule.style.getPropertyValue(aProperty);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1214,7 +1214,7 @@ CssRule.prototype = {
|
|||
*/
|
||||
getPropertyPriority: function(aProperty)
|
||||
{
|
||||
return this._domRule.style.getPropertyPriority(aProperty);
|
||||
return this.domRule.style.getPropertyPriority(aProperty);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1232,11 +1232,11 @@ CssRule.prototype = {
|
|||
// Parse the CSSStyleRule.selectorText string.
|
||||
this._selectors = [];
|
||||
|
||||
if (!this._domRule.selectorText) {
|
||||
if (!this.domRule.selectorText) {
|
||||
return this._selectors;
|
||||
}
|
||||
|
||||
let selectors = CssLogic.getSelectors(this._domRule);
|
||||
let selectors = CssLogic.getSelectors(this.domRule);
|
||||
|
||||
for (let i = 0, len = selectors.length; i < len; i++) {
|
||||
this._selectors.push(new CssSelector(this, selectors[i], i));
|
||||
|
@ -1247,7 +1247,7 @@ CssRule.prototype = {
|
|||
|
||||
toString: function CssRule_toString()
|
||||
{
|
||||
return "[CssRule " + this._domRule.selectorText + "]";
|
||||
return "[CssRule " + this.domRule.selectorText + "]";
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1262,7 +1262,7 @@ CssRule.prototype = {
|
|||
*/
|
||||
function CssSelector(aCssRule, aSelector, aIndex)
|
||||
{
|
||||
this._cssRule = aCssRule;
|
||||
this.cssRule = aCssRule;
|
||||
this.text = aSelector;
|
||||
this.elementStyle = this.text == "@element.style";
|
||||
this._specificity = null;
|
||||
|
@ -1282,7 +1282,7 @@ CssSelector.prototype = {
|
|||
*/
|
||||
get source()
|
||||
{
|
||||
return this._cssRule.source;
|
||||
return this.cssRule.source;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1294,7 +1294,7 @@ CssSelector.prototype = {
|
|||
*/
|
||||
get sourceElement()
|
||||
{
|
||||
return this._cssRule.sourceElement;
|
||||
return this.cssRule.sourceElement;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1305,7 +1305,7 @@ CssSelector.prototype = {
|
|||
*/
|
||||
get href()
|
||||
{
|
||||
return this._cssRule.href;
|
||||
return this.cssRule.href;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1316,7 +1316,7 @@ CssSelector.prototype = {
|
|||
*/
|
||||
get contentRule()
|
||||
{
|
||||
return this._cssRule.contentRule;
|
||||
return this.cssRule.contentRule;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1327,7 +1327,7 @@ CssSelector.prototype = {
|
|||
*/
|
||||
get sheetAllowed()
|
||||
{
|
||||
return this._cssRule.sheetAllowed;
|
||||
return this.cssRule.sheetAllowed;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1338,7 +1338,7 @@ CssSelector.prototype = {
|
|||
*/
|
||||
get sheetIndex()
|
||||
{
|
||||
return this._cssRule.sheetIndex;
|
||||
return this.cssRule.sheetIndex;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1349,7 +1349,7 @@ CssSelector.prototype = {
|
|||
*/
|
||||
get ruleLine()
|
||||
{
|
||||
return this._cssRule.line;
|
||||
return this.cssRule.line;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1391,7 +1391,7 @@ CssSelector.prototype = {
|
|||
return this._specificity;
|
||||
}
|
||||
|
||||
this._specificity = domUtils.getSpecificity(this._cssRule._domRule,
|
||||
this._specificity = domUtils.getSpecificity(this.cssRule.domRule,
|
||||
this.selectorIndex);
|
||||
|
||||
return this._specificity;
|
||||
|
@ -1534,7 +1534,7 @@ CssPropertyInfo.prototype = {
|
|||
*/
|
||||
_processMatchedSelector: function CssPropertyInfo_processMatchedSelector(aSelector, aStatus)
|
||||
{
|
||||
let cssRule = aSelector._cssRule;
|
||||
let cssRule = aSelector.cssRule;
|
||||
let value = cssRule.getPropertyValue(this.property);
|
||||
if (value &&
|
||||
(aStatus == CssLogic.STATUS.MATCHED ||
|
||||
|
@ -1560,7 +1560,7 @@ CssPropertyInfo.prototype = {
|
|||
let ruleCount = 0;
|
||||
|
||||
let iterator = function(aSelectorInfo) {
|
||||
let cssRule = aSelectorInfo.selector._cssRule;
|
||||
let cssRule = aSelectorInfo.selector.cssRule;
|
||||
if (cssRule._passId != passId) {
|
||||
if (cssRule.sheetAllowed) {
|
||||
ruleCount++;
|
||||
|
@ -1604,7 +1604,7 @@ function CssSelectorInfo(aSelector, aProperty, aValue, aStatus)
|
|||
this.value = aValue;
|
||||
this.status = aStatus;
|
||||
|
||||
let priority = this.selector._cssRule.getPropertyPriority(this.property);
|
||||
let priority = this.selector.cssRule.getPropertyPriority(this.property);
|
||||
this.important = (priority === "important");
|
||||
}
|
||||
|
||||
|
|
|
@ -827,7 +827,7 @@ LinuxNativeApp.prototype = {
|
|||
.getService(Ci.nsIToolkitProfileService);
|
||||
|
||||
try {
|
||||
this.appProfile = profSvc.createDefaultProfileForApp(this.installDir.leafName,
|
||||
this.appProfile = profSvc.createDefaultProfileForApp(this.uniqueName,
|
||||
null, null);
|
||||
} catch (ex if ex.result == Cr.NS_ERROR_ALREADY_INITIALIZED) {}
|
||||
},
|
||||
|
|
Загрузка…
Ссылка в новой задаче