Bug 702577 - Show font-family tooltip r=mratcliffe

This commit is contained in:
Michael Ratcliffe 2014-03-10 13:24:58 +00:00
parent 5bbbe857fc
commit 0ef4f577a8
9 changed files with 344 additions and 1 deletions

View File

@ -745,6 +745,40 @@ Tooltip.prototype = {
def.reject();
}
return def.promise;
},
/**
* Set the content of the tooltip to display a font family preview.
* This is based on Lea Verou's Dablet. See https://github.com/LeaVerou/dabblet
* for more info.
*
* @param {String} font
* The font family value.
*/
setFontFamilyContent: function(font) {
let def = promise.defer();
if (font) {
// Main container
let vbox = this.doc.createElement("vbox");
vbox.setAttribute("flex", "1");
// Display the font family previewer
let previewer = this.doc.createElement("description");
previewer.setAttribute("flex", "1");
previewer.style.fontFamily = font;
previewer.classList.add("devtools-tooltip-font-previewer-text");
previewer.textContent = "(ABCabc123&@%)";
vbox.appendChild(previewer);
this.content = vbox;
def.resolve();
} else {
def.reject();
}
return def.promise;
}
};

View File

@ -531,14 +531,20 @@ CssHtmlTree.prototype = {
}
}
// Test for css transform
if (target.classList.contains("property-value")) {
let propValue = target;
let propName = target.parentNode.querySelector(".property-name");
// Test for css transform
if (propName.textContent === "transform") {
return this.tooltip.setCssTransformContent(propValue.textContent,
this.pageStyle, this.viewedElement);
}
// Test for font family
if (propName.textContent === "font-family") {
return this.tooltip.setFontFamilyContent(propValue.textContent);
}
}
// If the target isn't one that should receive a tooltip, signal it by rejecting

View File

@ -1142,6 +1142,27 @@ CssRuleView.prototype = {
}
}
// Get the nodes containing the property name and property value,
// and test for font family
let propertyRoot = target.parentNode;
let propertyNameNode = propertyRoot.querySelector(".ruleview-propertyname");
if (!propertyNameNode) {
propertyRoot = propertyRoot.parentNode;
propertyNameNode = propertyRoot.querySelector(".ruleview-propertyname");
}
let propertyName;
if (propertyNameNode) {
propertyName = propertyNameNode.textContent;
}
if (propertyName === "font-family" &&
target.classList.contains("ruleview-propertyvalue")) {
this.previewTooltip.setFontFamilyContent(target.textContent).then(def.resolve);
hasTooltip = true;
}
if (hasTooltip) {
this.colorPicker.revert();
this.colorPicker.hide();

View File

@ -56,6 +56,8 @@ support-files = browser_ruleview_pseudoelement.html
[browser_bug765105_background_image_tooltip.js]
[browser_bug889638_rule_view_color_picker.js]
[browser_bug726427_csstransform_tooltip.js]
[browser_bug702577_fontfamily_tooltip_shorthand.js]
[browser_bug702577_fontfamily_tooltip_longhand.js]
[browser_bug940500_rule_view_pick_gradient_color.js]
[browser_ruleview_original_source_link.js]
support-files =

View File

@ -0,0 +1,131 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let contentDoc;
let inspector;
let ruleView;
let computedView;
const PAGE_CONTENT = [
'<style type="text/css">',
' #testElement {',
' font-family: cursive;',
' color: #333;',
' padding-left: 70px;',
' }',
'</style>',
'<div id="testElement">test element</div>'
].join("\n");
function test() {
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
contentDoc = content.document;
waitForFocus(createDocument, content);
}, true);
content.location = "data:text/html;charset=utf-8,font family longhand tooltip test";
}
function createDocument() {
contentDoc.body.innerHTML = PAGE_CONTENT;
openRuleView((aInspector, aRuleView) => {
inspector = aInspector;
ruleView = aRuleView;
startTests();
});
}
function startTests() {
inspector.selection.setNode(contentDoc.querySelector("#testElement"));
inspector.once("inspector-updated", testRuleView);
}
function endTests() {
contentDoc = inspector = ruleView = computedView = null;
gBrowser.removeCurrentTab();
finish();
}
function assertTooltipShownOn(tooltip, element, cb) {
// If there is indeed a show-on-hover on element, the xul panel will be shown
tooltip.panel.addEventListener("popupshown", function shown() {
tooltip.panel.removeEventListener("popupshown", shown, true);
cb();
}, true);
tooltip._showOnHover(element);
}
function testRuleView() {
info("Testing font-family tooltips in the rule view");
let panel = ruleView.previewTooltip.panel;
// Check that the rule view has a tooltip and that a XUL panel has been created
ok(ruleView.previewTooltip, "Tooltip instance exists");
ok(panel, "XUL panel exists");
// Get the font family property inside the rule view
let {valueSpan} = getRuleViewProperty("font-family");
// And verify that the tooltip gets shown on this property
assertTooltipShownOn(ruleView.previewTooltip, valueSpan, () => {
let description = panel.getElementsByTagName("description")[0];
is(description.style.fontFamily, "cursive", "Tooltips contains correct font-family style");
ruleView.previewTooltip.hide();
testComputedView();
});
}
function testComputedView() {
info("Testing font-family tooltips in the computed view");
inspector.sidebar.select("computedview");
computedView = inspector.sidebar.getWindowForTab("computedview").computedview.view;
let doc = computedView.styleDocument;
let panel = computedView.tooltip.panel;
let {valueSpan} = getComputedViewProperty("font-family");
assertTooltipShownOn(computedView.tooltip, valueSpan, () => {
let description = panel.getElementsByTagName("description")[0];
is(description.style.fontFamily, "cursive", "Tooltips contains correct font-family style");
computedView.tooltip.hide();
endTests();
});
}
function getRuleViewProperty(name) {
let prop = null;
[].forEach.call(ruleView.doc.querySelectorAll(".ruleview-property"), property => {
let nameSpan = property.querySelector(".ruleview-propertyname");
let valueSpan = property.querySelector(".ruleview-propertyvalue");
if (nameSpan.textContent === name) {
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
}
});
return prop;
}
function getComputedViewProperty(name) {
let prop = null;
[].forEach.call(computedView.styleDocument.querySelectorAll(".property-view"), property => {
let nameSpan = property.querySelector(".property-name");
let valueSpan = property.querySelector(".property-value");
if (nameSpan.textContent === name) {
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
}
});
return prop;
}

View File

@ -0,0 +1,133 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let contentDoc;
let inspector;
let ruleView;
let computedView;
const PAGE_CONTENT = [
'<style type="text/css">',
' #testElement {',
' font: italic bold .8em/1.2 Arial;',
' }',
'</style>',
'<div id="testElement">test element</div>'
].join("\n");
function test() {
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
contentDoc = content.document;
waitForFocus(createDocument, content);
}, true);
content.location = "data:text/html;charset=utf-8,font family shorthand tooltip test";
}
function createDocument() {
contentDoc.body.innerHTML = PAGE_CONTENT;
openRuleView((aInspector, aRuleView) => {
inspector = aInspector;
ruleView = aRuleView;
startTests();
});
}
function startTests() {
inspector.selection.setNode(contentDoc.querySelector("#testElement"));
inspector.once("inspector-updated", testRuleView);
}
function endTests() {
contentDoc = inspector = ruleView = computedView = null;
gBrowser.removeCurrentTab();
finish();
}
function assertTooltipShownOn(tooltip, element, cb) {
// If there is indeed a show-on-hover on element, the xul panel will be shown
tooltip.panel.addEventListener("popupshown", function shown() {
tooltip.panel.removeEventListener("popupshown", shown, true);
cb();
}, true);
tooltip._showOnHover(element);
}
function testRuleView() {
info("Testing font-family tooltips in the rule view");
let panel = ruleView.previewTooltip.panel;
// Check that the rule view has a tooltip and that a XUL panel has been created
ok(ruleView.previewTooltip, "Tooltip instance exists");
ok(panel, "XUL panel exists");
// Get the computed font family property inside the font rule view
let propertyList = ruleView.element.querySelectorAll(".ruleview-propertylist");
let fontExpander = propertyList[1].querySelectorAll(".ruleview-expander")[0];
fontExpander.click();
let {valueSpan} = getRuleViewProperty("font-family");
// And verify that the tooltip gets shown on this property
assertTooltipShownOn(ruleView.previewTooltip, valueSpan, () => {
let description = panel.getElementsByTagName("description")[0];
is(description.style.fontFamily, "Arial", "Tooltips contains correct font-family style");
ruleView.previewTooltip.hide();
testComputedView();
});
}
function testComputedView() {
info("Testing font-family tooltips in the computed view");
inspector.sidebar.select("computedview");
computedView = inspector.sidebar.getWindowForTab("computedview").computedview.view;
let doc = computedView.styleDocument;
let panel = computedView.tooltip.panel;
let {valueSpan} = getComputedViewProperty("font-family");
assertTooltipShownOn(computedView.tooltip, valueSpan, () => {
let description = panel.getElementsByTagName("description")[0];
is(description.style.fontFamily, "Arial", "Tooltips contains correct font-family style");
computedView.tooltip.hide();
endTests();
});
}
function getRuleViewProperty(name) {
let prop = null;
[].forEach.call(ruleView.doc.querySelectorAll(".ruleview-computedlist"), property => {
let nameSpan = property.querySelector(".ruleview-propertyname");
let valueSpan = property.querySelector(".ruleview-propertyvalue");
if (nameSpan.textContent === name) {
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
}
});
return prop;
}
function getComputedViewProperty(name) {
let prop = null;
[].forEach.call(computedView.styleDocument.querySelectorAll(".property-view"), property => {
let nameSpan = property.querySelector(".property-name");
let valueSpan = property.querySelector(".property-value");
if (nameSpan.textContent === name) {
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
}
});
return prop;
}

View File

@ -174,6 +174,14 @@
margin-bottom: -4px;
}
/* Tooltip: Font Family Previewer Text */
.devtools-tooltip-font-previewer-text {
max-width: 400px;
line-height: 1.5;
font-size: 150%;
text-align: center;
}
/* Tooltip: Alert Icon */
.devtools-tooltip-alert-icon {

View File

@ -312,6 +312,10 @@ div.CodeMirror span.eval-text {
border-bottom: 1px solid #434850;
}
.theme-tooltip-panel .devtools-tooltip-font-previewer-text {
color: white;
}
.theme-tooltip-panel .devtools-tooltip-simple-text:last-child {
border-bottom: 0;
}

View File

@ -321,6 +321,10 @@ div.CodeMirror span.eval-text {
border-bottom: 1px solid #d9e1e8;
}
.theme-tooltip-panel .devtools-tooltip-font-previewer-text {
color: black;
}
.theme-tooltip-panel .devtools-tooltip-simple-text:last-child {
border-bottom: 0;
}