author | Julian Descottes <jdescottes@mozilla.com> |
Tue, 05 Jul 2016 14:39:52 +0200 | |
changeset 304908 | 395c5a486954a3f747ceb07dfc8f1ebd3d00cf60 |
parent 304907 | 9efa66f1c6a15449be7a3c37ade8e104ce2afef8 |
child 304909 | b8b27cb2e148119595af75ff7ee3c2af1b7e833a |
push id | 30446 |
push user | cbook@mozilla.com |
push date | Thu, 14 Jul 2016 09:44:34 +0000 |
treeherder | mozilla-central@cd9da00ffcc3 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | ochameau |
bugs | 1283454 |
milestone | 50.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/devtools/client/inspector/rules/test/browser_rules_context-menu-show-mdn-docs-02.js +++ b/devtools/client/inspector/rules/test/browser_rules_context-menu-show-mdn-docs-02.js @@ -7,17 +7,17 @@ * with the MDN docs tooltip. * * If you display the context click on a property name in the rule view, you * should see a menu item "Show MDN Docs". If you click that item, the MDN * docs tooltip should be shown, containing docs from MDN for that property. * * This file tests that: * - clicking the context menu item shows the tooltip - * - pressing "Escape" while the tooltip is showing hides the tooltip + * - the tooltip content matches the property name for which the context menu was opened */ "use strict"; const {setBaseCssDocsUrl} = require("devtools/client/shared/widgets/MdnDocsWidget"); const PROPERTYNAME = "color"; @@ -31,20 +31,17 @@ const TEST_DOC = ` </body> </html> `; add_task(function* () { yield addTab("data:text/html;charset=utf8," + encodeURIComponent(TEST_DOC)); let {inspector, view} = yield openRuleView(); yield selectNode("div", inspector); - yield testShowAndHideMdnTooltip(view); -}); -function* testShowMdnTooltip(view) { setBaseCssDocsUrl(URL_ROOT); info("Setting the popupNode for the MDN docs tooltip"); let {nameSpan} = getRuleViewProperty(view, "element", PROPERTYNAME); let allMenuItems = openStyleContextMenuAndGetAllItems(view, nameSpan.firstChild); let menuitemShowMdnDocs = allMenuItems.find(item => item.label === @@ -52,35 +49,13 @@ function* testShowMdnTooltip(view) { let cssDocs = view.tooltips.cssDocs; info("Showing the MDN docs tooltip"); let onShown = cssDocs.tooltip.once("shown"); menuitemShowMdnDocs.click(); yield onShown; ok(true, "The MDN docs tooltip was shown"); -} - -/** - * Test that: - * - the MDN tooltip is shown when we click the context menu item - * - the tooltip's contents have been initialized (we don't fully - * test this here, as it's fully tested with the tooltip test code) - * - the tooltip is hidden when we press Escape - */ -function* testShowAndHideMdnTooltip(view) { - yield testShowMdnTooltip(view); info("Quick check that the tooltip contents are set"); - let cssDocs = view.tooltips.cssDocs; - - // FIXME: Remove the comment below when bug 1246896 is fixed. - /* eslint-disable mozilla/no-cpows-in-tests */ - let tooltipDocument = cssDocs.tooltip.content.contentDocument; - let h1 = tooltipDocument.getElementById("property-name"); + let h1 = cssDocs.tooltip.container.querySelector(".mdn-property-name"); is(h1.textContent, PROPERTYNAME, "The MDN docs tooltip h1 is correct"); - - info("Simulate pressing the 'Escape' key"); - let onHidden = cssDocs.tooltip.once("hidden"); - EventUtils.sendKey("escape"); - yield onHidden; - ok(true, "The MDN docs tooltip was hidden on pressing 'escape'"); -} +});
new file mode 100644 --- /dev/null +++ b/devtools/client/inspector/rules/test/browser_rules_css-docs-tooltip_closes-on-escape.js @@ -0,0 +1,51 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test that the CssDocs tooltip of the ruleview can be closed when pressing the Escape + * key. + */ + +"use strict"; + +const {setBaseCssDocsUrl} = + require("devtools/client/shared/widgets/MdnDocsWidget"); + +const PROPERTYNAME = "color"; + +const TEST_URI = ` + <html> + <body> + <div style="color: red"> + Test "Show MDN Docs" closes on escape + </div> + </body> + </html> +`; + +/** + * Test that the tooltip is hidden when we press Escape + */ +add_task(function* () { + yield addTab("data:text/html;charset=utf8," + encodeURIComponent(TEST_URI)); + let {inspector, view} = yield openRuleView(); + yield selectNode("div", inspector); + + setBaseCssDocsUrl(URL_ROOT); + + info("Retrieve a valid anchor for the CssDocs tooltip"); + let {nameSpan} = getRuleViewProperty(view, "element", PROPERTYNAME); + + info("Showing the MDN docs tooltip"); + let onShown = view.tooltips.cssDocs.tooltip.once("shown"); + view.tooltips.cssDocs.show(nameSpan, PROPERTYNAME); + yield onShown; + ok(true, "The MDN docs tooltip was shown"); + + info("Simulate pressing the 'Escape' key"); + let onHidden = view.tooltips.cssDocs.tooltip.once("hidden"); + EventUtils.sendKey("escape"); + yield onHidden; + ok(true, "The MDN docs tooltip was hidden on pressing 'escape'"); +});
--- a/devtools/client/inspector/shared/style-inspector-overlays.js +++ b/devtools/client/inspector/shared/style-inspector-overlays.js @@ -15,19 +15,21 @@ const {getColor} = require("devtools/client/shared/theme"); const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); const { getImageDimensions, setImageTooltip, setBrokenImageTooltip, } = require("devtools/client/shared/widgets/tooltip/ImageTooltipHelper"); const { + CssDocsTooltip, +} = require("devtools/client/shared/widgets/tooltip/CssDocsTooltip"); +const { SwatchColorPickerTooltip, SwatchCubicBezierTooltip, - CssDocsTooltip, SwatchFilterTooltip } = require("devtools/client/shared/widgets/Tooltip"); const EventEmitter = require("devtools/shared/event-emitter"); const promise = require("promise"); const {Task} = require("devtools/shared/task"); const Services = require("Services"); const PREF_IMAGE_TOOLTIP_SIZE = "devtools.inspector.imagePreviewTooltipSize"; @@ -271,32 +273,31 @@ TooltipsOverlay.prototype = { * Add the tooltips overlay to the view. This will start tracking mouse * movements and display tooltips when needed */ addToView: function () { if (this._isStarted || this._isDestroyed) { return; } - let panelDoc = this.view.inspector.panelDoc; + let { toolbox } = this.view.inspector; // Image, fonts, ... preview tooltip - this.previewTooltip = new HTMLTooltip(this.view.inspector.toolbox, { + this.previewTooltip = new HTMLTooltip(toolbox, { type: "arrow", useXulWrapper: true }); this.previewTooltip.startTogglingOnHover(this.view.element, this._onPreviewTooltipTargetHover.bind(this)); // MDN CSS help tooltip - this.cssDocs = new CssDocsTooltip(panelDoc); + this.cssDocs = new CssDocsTooltip(toolbox); if (this.isRuleView) { // Color picker tooltip - let { toolbox } = this.view.inspector; this.colorPicker = new SwatchColorPickerTooltip(toolbox); // Cubic bezier tooltip this.cubicBezier = new SwatchCubicBezierTooltip(toolbox); // Filter editor tooltip this.filterEditor = new SwatchFilterTooltip(toolbox); } this._isStarted = true; @@ -388,17 +389,17 @@ TooltipsOverlay.prototype = { this.colorPicker.hide(); } if (this.isRuleView && this.cubicBezier.tooltip.isVisible()) { this.cubicBezier.revert(); this.cubicBezier.hide(); } - if (this.isRuleView && this.cssDocs.tooltip.isShown()) { + if (this.isRuleView && this.cssDocs.tooltip.isVisible()) { this.cssDocs.hide(); } if (this.isRuleView && this.filterEditor.tooltip.isVisible()) { this.filterEditor.revert(); this.filterEdtior.hide(); }
--- a/devtools/client/jar.mn +++ b/devtools/client/jar.mn @@ -123,17 +123,16 @@ devtools.jar: content/framework/dev-edition-promo/dev-edition-logo.png (framework/dev-edition-promo/dev-edition-logo.png) content/inspector/inspector.xul (inspector/inspector.xul) content/inspector/inspector.css (inspector/inspector.css) content/framework/connect/connect.xhtml (framework/connect/connect.xhtml) content/framework/connect/connect.css (framework/connect/connect.css) content/framework/connect/connect.js (framework/connect/connect.js) content/shared/widgets/graphs-frame.xhtml (shared/widgets/graphs-frame.xhtml) content/shared/widgets/cubic-bezier.css (shared/widgets/cubic-bezier.css) - content/shared/widgets/mdn-docs-frame.xhtml (shared/widgets/mdn-docs-frame.xhtml) content/shared/widgets/mdn-docs.css (shared/widgets/mdn-docs.css) content/shared/widgets/filter-widget.css (shared/widgets/filter-widget.css) content/shared/widgets/spectrum.css (shared/widgets/spectrum.css) content/eyedropper/eyedropper.xul (eyedropper/eyedropper.xul) content/eyedropper/crosshairs.css (eyedropper/crosshairs.css) content/eyedropper/nocursor.css (eyedropper/nocursor.css) content/aboutdebugging/aboutdebugging.xhtml (aboutdebugging/aboutdebugging.xhtml) content/aboutdebugging/aboutdebugging.css (aboutdebugging/aboutdebugging.css)
--- a/devtools/client/shared/test/browser_mdn-docs-01.js +++ b/devtools/client/shared/test/browser_mdn-docs-01.js @@ -15,22 +15,18 @@ * * In this file we test: * - the initial state of the document before the docs have loaded * - the state of the document after the docs have loaded */ "use strict"; -const {CssDocsTooltip} = require("devtools/client/shared/widgets/Tooltip"); const {setBaseCssDocsUrl, MdnDocsWidget} = require("devtools/client/shared/widgets/MdnDocsWidget"); -// frame to load the tooltip into -const MDN_DOCS_TOOLTIP_FRAME = "chrome://devtools/content/shared/widgets/mdn-docs-frame.xhtml"; - /** * Test properties * * In the real tooltip, a CSS property name is used to look up an MDN page * for that property. * In the test code, the names defined here is used to look up a page * served by the test server. */ @@ -40,24 +36,26 @@ const BASIC_EXPECTED_SUMMARY = "A summar const BASIC_EXPECTED_SYNTAX = [{type: "comment", text: "/* The part we want */"}, {type: "text", text: "\n"}, {type: "property-name", text: "this"}, {type: "text", text: ":"}, {type: "text", text: " "}, {type: "property-value", text: "is-the-part-we-want"}, {type: "text", text: ";"}]; -const URI_PARAMS = "?utm_source=mozilla&utm_medium=firefox-inspector&utm_campaign=default"; +const URI_PARAMS = + "?utm_source=mozilla&utm_medium=firefox-inspector&utm_campaign=default"; add_task(function* () { setBaseCssDocsUrl(TEST_URI_ROOT); yield addTab("about:blank"); - let [host, win, doc] = yield createHost("bottom", MDN_DOCS_TOOLTIP_FRAME); - let widget = new MdnDocsWidget(win.document); + let [host, win] = yield createHost("bottom", "data:text/html," + + "<div class='mdn-container'></div>"); + let widget = new MdnDocsWidget(win.document.querySelector("div")); yield testTheBasics(widget); host.destroy(); gBrowser.removeCurrentTab(); }); /**
--- a/devtools/client/shared/test/browser_mdn-docs-02.js +++ b/devtools/client/shared/test/browser_mdn-docs-02.js @@ -16,21 +16,20 @@ * error conditions like parts of the document being missing. * * We also test that the tooltip properly handles the case where the page * doesn't exist at all. */ "use strict"; -const {CssDocsTooltip} = require("devtools/client/shared/widgets/Tooltip"); -const {setBaseCssDocsUrl, MdnDocsWidget} = require("devtools/client/shared/widgets/MdnDocsWidget"); - -// frame to load the tooltip into -const MDN_DOCS_TOOLTIP_FRAME = "chrome://devtools/content/shared/widgets/mdn-docs-frame.xhtml"; +const { + setBaseCssDocsUrl, + MdnDocsWidget +} = require("devtools/client/shared/widgets/MdnDocsWidget"); const BASIC_EXPECTED_SUMMARY = "A summary of the property."; const BASIC_EXPECTED_SYNTAX = [{type: "comment", text: "/* The part we want */"}, {type: "text", text: "\n"}, {type: "property-name", text: "this"}, {type: "text", text: ":"}, {type: "text", text: " "}, {type: "property-value", text: "is-the-part-we-want"}, @@ -95,43 +94,33 @@ const TEST_DATA = [{ } } ]; add_task(function* () { setBaseCssDocsUrl(TEST_URI_ROOT); yield addTab("about:blank"); - let [host, win, doc] = yield createHost("bottom", MDN_DOCS_TOOLTIP_FRAME); - let widget = new MdnDocsWidget(win.document); + let [host, win] = yield createHost("bottom", "data:text/html," + + "<div class='mdn-container'></div>"); + let widget = new MdnDocsWidget(win.document.querySelector("div")); for (let {desc, docsPageUrl, expectedContents} of TEST_DATA) { info(desc); yield widget.loadCssDocs(docsPageUrl); checkTooltipContents(widget.elements, expectedContents); } host.destroy(); gBrowser.removeCurrentTab(); }); -function* testNonExistentPage(widget) { - info("Test a property for which we don't have a page"); - yield widget.loadCssDocs("i-dont-exist.html"); - checkTooltipContents(widget.elements, { - propertyName: "i-dont-exist.html", - summary: ERROR_MESSAGE, - syntax: "" - }); -} - /* * Utility function to check content of the tooltip. */ function checkTooltipContents(doc, expected) { - is(doc.heading.textContent, expected.propertyName, "Property name is correct"); is(doc.summary.textContent, expected.summary, "Summary is correct");
--- a/devtools/client/shared/widgets/MdnDocsWidget.js +++ b/devtools/client/shared/widgets/MdnDocsWidget.js @@ -24,16 +24,18 @@ "use strict"; const Services = require("Services"); const defer = require("devtools/shared/defer"); const {getCSSLexer} = require("devtools/shared/css-lexer"); const {gDevTools} = require("devtools/client/framework/devtools"); +const XHTML_NS = "http://www.w3.org/1999/xhtml"; + // Parameters for the XHR request // see https://developer.mozilla.org/en-US/docs/MDN/Kuma/API#Document_parameters const XHR_PARAMS = "?raw¯os"; // URL for the XHR request var XHR_CSS_URL = "https://developer.mozilla.org/en-US/docs/Web/CSS/"; // Parameters for the link to MDN in the tooltip, so // so we know which MDN visits come from this feature @@ -82,17 +84,17 @@ function appendSyntaxHighlightedCSS(cssT let doc = parentElement.ownerDocument; let identClass = PROPERTY_NAME_COLOR; let lexer = getCSSLexer(cssText); /** * Create a SPAN node with the given text content and class. */ function createStyledNode(textContent, className) { - let newNode = doc.createElement("span"); + let newNode = doc.createElementNS(XHTML_NS, "span"); newNode.classList.add(className); newNode.textContent = textContent; return newNode; } /** * If the symbol is ":", we will expect the next * "ident" token to be part of a property value. @@ -219,42 +221,49 @@ function getCssDocs(cssProperty) { return deferred.promise; } exports.getCssDocs = getCssDocs; /** * The MdnDocsWidget is used by tooltip code that needs to display docs - * from MDN in a tooltip. The tooltip code loads a document that contains the - * basic structure of a docs tooltip (loaded from mdn-docs-frame.xhtml), - * and passes this document into the widget's constructor. + * from MDN in a tooltip. * * In the constructor, the widget does some general setup that's not * dependent on the particular item we need docs for. * * After that, when the tooltip code needs to display docs for an item, it * asks the widget to retrieve the docs and update the document with them. * - * @param {Document} tooltipDocument - * A DOM document. The widget expects the document to have a particular - * structure. + * @param {Element} tooltipContainer + * A DOM element where the MdnDocs widget markup should be created. */ -function MdnDocsWidget(tooltipDocument) { +function MdnDocsWidget(tooltipContainer) { + tooltipContainer.innerHTML = + `<header> + <h1 class="mdn-property-name theme-fg-color5"></h1> + </header> + <div class="mdn-property-info"> + <div class="mdn-summary"></div> + <pre class="mdn-syntax devtools-monospace"></pre> + </div> + <footer> + <a class="mdn-visit-page theme-link" href="#">Visit MDN (placeholder)</a> + </footer>`; + // fetch all the bits of the document that we will manipulate later this.elements = { - heading: tooltipDocument.getElementById("property-name"), - summary: tooltipDocument.getElementById("summary"), - syntax: tooltipDocument.getElementById("syntax"), - info: tooltipDocument.getElementById("property-info"), - linkToMdn: tooltipDocument.getElementById("visit-mdn-page") + heading: tooltipContainer.querySelector(".mdn-property-name"), + summary: tooltipContainer.querySelector(".mdn-summary"), + syntax: tooltipContainer.querySelector(".mdn-syntax"), + info: tooltipContainer.querySelector(".mdn-property-info"), + linkToMdn: tooltipContainer.querySelector(".mdn-visit-page") }; - this.doc = tooltipDocument; - // get the localized string for the link text this.elements.linkToMdn.textContent = l10n.strings.GetStringFromName("docsTooltip.visitMDN"); // listen for clicks and open in the browser window instead let mainWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType); this.elements.linkToMdn.addEventListener("click", function (e) { e.stopPropagation(); @@ -352,17 +361,16 @@ MdnDocsWidget.prototype = { initializeDocument(propertyName); getCssDocs(propertyName).then(finalizeDocument, gotError); return deferred.promise; }, destroy: function () { this.elements = null; - this.doc = null; } }; /** * L10N utility class */ function L10N() {} L10N.prototype = {};
--- a/devtools/client/shared/widgets/Tooltip.js +++ b/devtools/client/shared/widgets/Tooltip.js @@ -4,17 +4,16 @@ "use strict"; const {Ci} = require("chrome"); const defer = require("devtools/shared/defer"); const {Spectrum} = require("devtools/client/shared/widgets/Spectrum"); const {CubicBezierWidget} = require("devtools/client/shared/widgets/CubicBezierWidget"); -const {MdnDocsWidget} = require("devtools/client/shared/widgets/MdnDocsWidget"); const {CSSFilterEditorWidget} = require("devtools/client/shared/widgets/FilterWidget"); const {TooltipToggle} = require("devtools/client/shared/widgets/tooltip/TooltipToggle"); const EventEmitter = require("devtools/shared/event-emitter"); const {colorUtils} = require("devtools/client/shared/css-color"); const Heritage = require("sdk/core/heritage"); const {Eyedropper} = require("devtools/client/eyedropper/eyedropper"); const {gDevTools} = require("devtools/client/framework/devtools"); const Services = require("Services"); @@ -28,19 +27,17 @@ loader.lazyRequireGetter(this, "clearNam loader.lazyRequireGetter(this, "setNamedTimeout", "devtools/client/shared/widgets/view-helpers", true); XPCOMUtils.defineLazyModuleGetter(this, "VariablesView", "resource://devtools/client/shared/widgets/VariablesView.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "VariablesViewController", "resource://devtools/client/shared/widgets/VariablesViewController.jsm"); const XHTML_NS = "http://www.w3.org/1999/xhtml"; -const MDN_DOCS_FRAME = "chrome://devtools/content/shared/widgets/mdn-docs-frame.xhtml"; const ESCAPE_KEYCODE = Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE; -const RETURN_KEYCODE = Ci.nsIDOMKeyEvent.DOM_VK_RETURN; const POPUP_EVENTS = ["shown", "hidden", "showing", "hiding"]; /** * Tooltip widget. * * This widget is intended at any tool that may need to show rich content in the * form of floating panels. * A common use case is image previewing in the CSS rule view, but more complex @@ -548,42 +545,16 @@ Tooltip.prototype = { // load the document from url into the iframe iframe.setAttribute("src", url); // Put the iframe in the tooltip this.content = iframe; return def.promise; - }, - - /** - * Set the content of this tooltip to the MDN docs widget. - * - * This is called when the tooltip is first constructed. - * - * @return {promise} A promise which is resolved with an MdnDocsWidget. - * - * It loads the tooltip's structure from a separate XHTML file - * into an iframe. When the iframe is loaded it constructs - * an MdnDocsWidget and passes that into resolve. - * - * The caller can use the MdnDocsWidget to update the tooltip's - * UI with new content each time the tooltip is shown. - */ - setMdnDocsContent: function () { - let dimensions = {width: "410", height: "300"}; - return this.setIFrameContent(dimensions, MDN_DOCS_FRAME).then(onLoaded); - - function onLoaded(iframe) { - let win = iframe.contentWindow.wrappedJSObject; - // create an MdnDocsWidget, initializing it with the content document - let widget = new MdnDocsWidget(win.document); - return widget; - } } }; /** * Base class for all (color, gradient, ...)-swatch based value editors inside * tooltips * * @param {Toolbox} toolbox @@ -1000,55 +971,16 @@ Heritage.extend(SwatchBasedEditorTooltip this.widget.then(widget => { widget.off("updated", this._onUpdate); widget.destroy(); }); } }); /** - * Tooltip for displaying docs for CSS properties from MDN. - * - * @param {XULDocument} doc - */ -function CssDocsTooltip(doc) { - this.tooltip = new Tooltip(doc, { - consumeOutsideClick: true, - closeOnKeys: [ESCAPE_KEYCODE, RETURN_KEYCODE], - noAutoFocus: false - }); - this.widget = this.tooltip.setMdnDocsContent(); -} - -module.exports.CssDocsTooltip = CssDocsTooltip; - -CssDocsTooltip.prototype = { - /** - * Load CSS docs for the given property, - * then display the tooltip. - */ - show: function (anchor, propertyName) { - function loadCssDocs(widget) { - return widget.loadCssDocs(propertyName); - } - - this.widget.then(loadCssDocs); - this.tooltip.show(anchor, "topcenter bottomleft"); - }, - - hide: function () { - this.tooltip.hide(); - }, - - destroy: function () { - this.tooltip.destroy(); - } -}; - -/** * The swatch-based css filter tooltip class is a specific class meant to be * used along with rule-view's generated css filter swatches. * It extends the parent SwatchBasedEditorTooltip class. * It just wraps a standard Tooltip and sets its content with an instance of a * CSSFilterEditorWidget. * * @param {Toolbox} toolbox * The devtools toolbox, needed to get the devtools main window.
deleted file mode 100644 --- a/devtools/client/shared/widgets/mdn-docs-frame.xhtml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- 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/. --> -<!DOCTYPE html> - -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> - <link rel="stylesheet" href="chrome://devtools/content/shared/widgets/mdn-docs.css" type="text/css"/> - <script type="application/javascript;version=1.8" src="chrome://devtools/content/shared/theme-switching.js"/> -</head> -<body class="theme-body"> - - <div id = "container"> - - <header> - <h1 id="property-name" class="theme-fg-color5"></h1> - </header> - - <div id="property-info"> - <div id="summary"></div> - <pre id="syntax" class="devtools-monospace"></pre> - </div> - - <footer> - <a id="visit-mdn-page" class="theme-link" href="#">Visit MDN (placeholder)</a> - </footer> - - </div> - -</body> -</html> \ No newline at end of file
--- a/devtools/client/shared/widgets/mdn-docs.css +++ b/devtools/client/shared/widgets/mdn-docs.css @@ -1,41 +1,39 @@ /* 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/. */ -#visit-mdn-page { - display: inline-block; - padding: 1em 0; -} - -html, body, #container { - height: 100%; - width: 100%; - margin: 0; - padding: 0; -} - -#container { +.mdn-container { + height: 300px; + margin: 4px; + overflow: auto; + box-sizing: border-box; display: flex; flex-direction: column; } -header, footer { +.mdn-container header, +.mdn-container footer { flex: 1; padding: 0 1em; } -#property-info { +.mdn-property-info { flex: 10; padding: 0 1em; overflow: auto; transition: opacity 400ms ease-in; } -#syntax { +.mdn-syntax { margin-top: 1em; } .devtools-throbber { + align-self: center; opacity: 0; - align-self: center; } + +.mdn-visit-page { + display: inline-block; + padding: 1em 0; +}
new file mode 100644 --- /dev/null +++ b/devtools/client/shared/widgets/tooltip/CssDocsTooltip.js @@ -0,0 +1,95 @@ +/* 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 {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {MdnDocsWidget} = require("devtools/client/shared/widgets/MdnDocsWidget"); +const XHTML_NS = "http://www.w3.org/1999/xhtml"; + +loader.lazyRequireGetter(this, "KeyShortcuts", + "devtools/client/shared/key-shortcuts", true); + +const TOOLTIP_WIDTH = 418; +const TOOLTIP_HEIGHT = 308; + +/** + * Tooltip for displaying docs for CSS properties from MDN. + * + * @param {Toolbox} toolbox + * Toolbox used to create the tooltip. + */ +function CssDocsTooltip(toolbox) { + this.tooltip = new HTMLTooltip(toolbox, { + type: "arrow", + consumeOutsideClicks: true, + autofocus: true, + useXulWrapper: true, + stylesheet: "chrome://devtools/content/shared/widgets/mdn-docs.css", + }); + this.widget = this.setMdnDocsContent(); + + // Initialize keyboard shortcuts + this.shortcuts = new KeyShortcuts({ window: toolbox.doc.defaultView }); + this._onShortcut = this._onShortcut.bind(this); + + this.shortcuts.on("Escape", this._onShortcut); + this.shortcuts.on("Return", this._onShortcut); +} + +module.exports.CssDocsTooltip = CssDocsTooltip; + +CssDocsTooltip.prototype = { + /** + * Load CSS docs for the given property, + * then display the tooltip. + */ + show: function (anchor, propertyName) { + this.tooltip.once("shown", () => { + this.widget.loadCssDocs(propertyName); + }); + this.tooltip.show(anchor); + }, + + hide: function () { + this.tooltip.hide(); + }, + + _onShortcut: function (shortcut, event) { + if (!this.tooltip.isVisible()) { + return; + } + + event.stopPropagation(); + if (shortcut === "Return") { + // If user is pressing return, do not prevent default and delay hiding the tooltip + // in case the focus is on the "Visit MDN page" link. + this.tooltip.doc.defaultView.setTimeout(this.hide.bind(this), 0); + } else { + // For any other key, preventDefault() and hide straight away. + event.preventDefault(); + this.hide(); + } + }, + + /** + * Set the content of this tooltip to the MDN docs widget. This is called when the + * tooltip is first constructed. + * The caller can use the MdnDocsWidget to update the tooltip's UI with new content + * each time the tooltip is shown. + * + * @return {MdnDocsWidget} the created MdnDocsWidget instance. + */ + setMdnDocsContent: function () { + let container = this.tooltip.doc.createElementNS(XHTML_NS, "div"); + container.setAttribute("class", "mdn-container theme-body"); + this.tooltip.setContent(container, {width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT}); + return new MdnDocsWidget(container); + }, + + destroy: function () { + this.shortcuts.destroy(); + this.tooltip.destroy(); + } +};
--- a/devtools/client/shared/widgets/tooltip/moz.build +++ b/devtools/client/shared/widgets/tooltip/moz.build @@ -1,11 +1,12 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # 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/. DevToolsModules( + 'CssDocsTooltip.js', 'EventTooltipHelper.js', 'ImageTooltipHelper.js', 'TooltipToggle.js', )