new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/actions/fonts.js
@@ -0,0 +1,23 @@
+/* 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 {
+ UPDATE_FONTS,
+} = require("./index");
+
+module.exports = {
+
+ /**
+ * Update the list of fonts in the font inspector
+ */
+ updateFonts(fonts) {
+ return {
+ type: UPDATE_FONTS,
+ fonts,
+ };
+ },
+
+};
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/actions/index.js
@@ -0,0 +1,20 @@
+/* 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 { createEnum } = require("devtools/client/shared/enum");
+
+createEnum([
+
+ // Update the list of fonts.
+ "UPDATE_FONTS",
+
+ // Update the preview test.
+ "UPDATE_PREVIEW_TEXT",
+
+ // Update whether to show all fonts.
+ "UPDATE_SHOW_ALL_FONTS",
+
+], module.exports);
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/actions/moz.build
@@ -0,0 +1,12 @@
+# -*- Mode: python; 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(
+ 'fonts.js',
+ 'index.js',
+ 'preview-text.js',
+ 'show-all-fonts.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/actions/preview-text.js
@@ -0,0 +1,23 @@
+/* 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 {
+ UPDATE_PREVIEW_TEXT,
+} = require("./index");
+
+module.exports = {
+
+ /**
+ * Update the preview text in the font inspector
+ */
+ updatePreviewText(previewText) {
+ return {
+ type: UPDATE_PREVIEW_TEXT,
+ previewText,
+ };
+ },
+
+};
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/actions/show-all-fonts.js
@@ -0,0 +1,23 @@
+/* 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 {
+ UPDATE_SHOW_ALL_FONTS,
+} = require("./index");
+
+module.exports = {
+
+ /**
+ * Update whether to show all fonts in the font inspector
+ */
+ updateShowAllFonts(showAllFonts) {
+ return {
+ type: UPDATE_SHOW_ALL_FONTS,
+ showAllFonts,
+ };
+ },
+
+};
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/components/App.js
@@ -0,0 +1,86 @@
+/* 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 { addons, createClass, createFactory, DOM: dom, PropTypes } =
+ require("devtools/client/shared/vendor/react");
+const { connect } = require("devtools/client/shared/vendor/react-redux");
+const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
+
+const SearchBox = createFactory(require("devtools/client/shared/components/search-box"));
+const FontList = createFactory(require("./FontList"));
+
+const { getStr } = require("../utils/l10n");
+const Types = require("../types");
+
+const PREVIEW_UPDATE_DELAY = 150;
+
+const App = createClass({
+
+ displayName: "App",
+
+ propTypes: {
+ fonts: PropTypes.arrayOf(PropTypes.shape(Types.font)).isRequired,
+ previewText: PropTypes.string.isRequired,
+ showAllFonts: PropTypes.bool.isRequired,
+ onPreviewFonts: PropTypes.func.isRequired,
+ onShowAllFontClick: PropTypes.func.isRequired,
+ onTextBoxContextMenu: PropTypes.func,
+ },
+
+ mixins: [ addons.PureRenderMixin ],
+
+ componentDidMount() {
+ let { onTextBoxContextMenu } = this.props;
+
+ let searchInput = findDOMNode(this).querySelector(".devtools-textinput");
+ searchInput.addEventListener("contextmenu", onTextBoxContextMenu);
+ },
+
+ componentWillUnmount() {
+ let { onTextBoxContextMenu } = this.props;
+
+ let searchInput = findDOMNode(this).querySelector(".devtools-textinput");
+ searchInput.removeEventListener("contextmenu", onTextBoxContextMenu);
+ },
+
+ render() {
+ let {
+ fonts,
+ onPreviewFonts,
+ onShowAllFontClick
+ } = this.props;
+
+ return dom.div(
+ {
+ className: "devtools-monospace theme-sidebar inspector-tabpanel",
+ id: "sidebar-panel-fontinspector"
+ },
+ dom.div(
+ {
+ className: "devtools-toolbar"
+ },
+ SearchBox({
+ delay: PREVIEW_UPDATE_DELAY,
+ placeholder: getStr("fontinspector.previewText"),
+ type: "text",
+ onChange: onPreviewFonts,
+ }),
+ dom.label(
+ {
+ id: "font-showall",
+ className: "theme-link",
+ title: getStr("fontinspector.seeAll.tooltip"),
+ onClick: onShowAllFontClick,
+ },
+ getStr("fontinspector.seeAll")
+ )
+ ),
+ FontList({ fonts })
+ );
+ }
+});
+
+module.exports = connect(state => state)(App);
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/components/Font.js
@@ -0,0 +1,153 @@
+/* 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 { addons, createClass, DOM: dom, PropTypes } = require("devtools/client/shared/vendor/react");
+
+const { getStr } = require("../utils/l10n");
+const Types = require("../types");
+
+module.exports = createClass({
+
+ displayName: "Font",
+
+ propTypes: PropTypes.shape(Types.font).isRequired,
+
+ mixins: [ addons.PureRenderMixin ],
+
+ getSectionClasses() {
+ let classes = ["font"];
+ classes.push((this.props.URI) ? "is-remote" : "is-local");
+
+ if (this.props.rule) {
+ classes.push("has-code");
+ }
+
+ return classes.join(" ");
+ },
+
+ renderFontPreview(previewUrl) {
+ return dom.div(
+ {
+ className: "font-preview-container",
+ },
+ dom.img(
+ {
+ className: "font-preview",
+ src: previewUrl
+ }
+ )
+ );
+ },
+
+ renderFontName(name) {
+ return dom.h1(
+ {
+ className: "font-name",
+ },
+ name
+ );
+ },
+
+ renderFontFormatURL(URI, format) {
+ return dom.p(
+ {
+ className: "font-format-url"
+ },
+ dom.input(
+ {
+ className: "font-url",
+ readOnly: "readonly",
+ value: URI
+ }
+ ),
+ " ",
+ format ?
+ dom.span(
+ {
+ className: "font-format"
+ },
+ format
+ )
+ :
+ dom.span(
+ {
+ className: "font-format",
+ hidden: "true"
+ },
+ format
+ )
+ );
+ },
+
+ renderFontCSS(cssFamilyName) {
+ return dom.p(
+ {
+ className: "font-css"
+ },
+ dom.span(
+ {},
+ getStr("fontinspector.usedAs")
+ ),
+ " \"",
+ dom.span(
+ {
+ className: "font-css-name"
+ },
+ cssFamilyName
+ ),
+ "\""
+ );
+ },
+
+ renderFontCSSCode(rule, ruleText) {
+ return dom.pre(
+ {
+ className: "font-css-code"
+ },
+ rule ? ruleText : null
+ );
+ },
+
+ render() {
+ let {
+ name,
+ cssFamilyName,
+ format,
+ URI,
+ rule,
+ ruleText,
+ previewUrl,
+ } = this.props;
+
+ return dom.section(
+ {
+ className: this.getSectionClasses(),
+ },
+ this.renderFontPreview(previewUrl),
+ dom.div(
+ {
+ className: "font-info",
+ },
+ this.renderFontName(name),
+ dom.span(
+ {
+ className: "font-is-local",
+ },
+ " " + getStr("fontinspector.system")
+ ),
+ dom.span(
+ {
+ className: "font-is-remote",
+ },
+ " " + getStr("fontinspector.remote")
+ ),
+ this.renderFontFormatURL(URI, format),
+ this.renderFontCSS(cssFamilyName),
+ this.renderFontCSSCode(rule, ruleText)
+ )
+ );
+ }
+});
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/components/FontList.js
@@ -0,0 +1,48 @@
+/* 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 { addons, createClass, createFactory, DOM: dom, PropTypes } =
+ require("devtools/client/shared/vendor/react");
+
+const Font = createFactory(require("./Font"));
+
+const Types = require("../types");
+
+module.exports = createClass({
+
+ displayName: "FontList",
+
+ propTypes: {
+ fonts: PropTypes.arrayOf(PropTypes.shape(Types.font)).isRequired
+ },
+
+ mixins: [ addons.PureRenderMixin ],
+
+ render() {
+ let { fonts } = this.props;
+
+ return dom.div(
+ {
+ id: "font-container"
+ },
+ dom.ul(
+ {
+ id: "all-fonts"
+ },
+ fonts.map(font => Font({
+ name: font.name,
+ cssFamilyName: font.CSSFamilyName,
+ format: font.format,
+ URI: font.URI,
+ rule: font.rule,
+ ruleText: font.ruleText,
+ previewUrl: font.previewUrl,
+ }))
+ )
+ );
+ },
+
+});
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/components/moz.build
@@ -0,0 +1,11 @@
+# -*- Mode: python; 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(
+ 'App.js',
+ 'Font.js',
+ 'FontList.js',
+)
--- a/devtools/client/inspector/fonts/fonts.js
+++ b/devtools/client/inspector/fonts/fonts.js
@@ -1,250 +1,189 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
+const Services = require("Services");
+
+const { createFactory, createElement } = require("devtools/client/shared/vendor/react");
+const { Provider } = require("devtools/client/shared/vendor/react-redux");
+
const {gDevTools} = require("devtools/client/framework/devtools");
+const App = createFactory(require("./components/App"));
+
+const { LocalizationHelper } = require("devtools/shared/l10n");
+const INSPECTOR_L10N =
+ new LocalizationHelper("devtools/client/locales/inspector.properties");
+
const DEFAULT_PREVIEW_TEXT = "Abc";
-const PREVIEW_UPDATE_DELAY = 150;
+
+const { updateFonts } = require("./actions/fonts");
+const { updatePreviewText } = require("./actions/preview-text");
+const { updateShowAllFonts } = require("./actions/show-all-fonts");
const {Task} = require("devtools/shared/task");
const {getColor} = require("devtools/client/shared/theme");
function FontInspector(inspector, window) {
+ this.document = window.document;
this.inspector = inspector;
this.pageStyle = this.inspector.pageStyle;
- this.chromeDoc = window.document;
- this.init();
+ this.store = inspector.store;
+
+ this.update = this.update.bind(this);
+ this.onNewNode = this.onNewNode.bind(this);
+ this.onPreviewFonts = this.onPreviewFonts.bind(this);
+ this.onShowAllFontClick = this.onShowAllFontClick.bind(this);
+ this.onThemeChanged = this.onThemeChanged.bind(this);
}
FontInspector.prototype = {
- init: function () {
- this.update = this.update.bind(this);
- this.onNewNode = this.onNewNode.bind(this);
- this.onThemeChanged = this.onThemeChanged.bind(this);
+
+ init() {
+ if (!this.inspector) {
+ return;
+ }
+
+ let app = App({
+ onPreviewFonts: this.onPreviewFonts,
+ onShowAllFontClick: this.onShowAllFontClick,
+ onTextBoxContextMenu: this.inspector.onTextBoxContextMenu
+ });
+
+ let provider = createElement(Provider, {
+ store: this.store,
+ id: "fontinspector",
+ title: INSPECTOR_L10N.getStr("inspector.sidebar.fontInspectorTitle"),
+ key: "fontinspector",
+ }, app);
+
+ let defaultTab = Services.prefs.getCharPref("devtools.inspector.activeSidebar");
+
+ this.inspector.addSidebarTab(
+ "fontinspector",
+ INSPECTOR_L10N.getStr("inspector.sidebar.fontInspectorTitle"),
+ provider,
+ defaultTab == "fontinspector"
+ );
+
this.inspector.selection.on("new-node-front", this.onNewNode);
this.inspector.sidebar.on("fontinspector-selected", this.onNewNode);
- this.showAll = this.showAll.bind(this);
- this.showAllLink = this.chromeDoc.getElementById("font-showall");
- this.showAllLink.addEventListener("click", this.showAll);
- this.previewTextChanged = this.previewTextChanged.bind(this);
- this.previewInput = this.chromeDoc.getElementById("font-preview-text-input");
- this.previewInput.addEventListener("input", this.previewTextChanged);
- this.previewInput.addEventListener("contextmenu",
- this.inspector.onTextBoxContextMenu);
// Listen for theme changes as the color of the previews depend on the theme
gDevTools.on("theme-switched", this.onThemeChanged);
- this.update();
- },
-
- /**
- * Is the fontinspector visible in the sidebar?
- */
- isActive: function () {
- return this.inspector.sidebar &&
- this.inspector.sidebar.getCurrentTabID() == "fontinspector";
+ this.store.dispatch(updatePreviewText(""));
+ this.store.dispatch(updateShowAllFonts(false));
+ this.update(false, "");
},
/**
- * Remove listeners.
+ * Destruction function called when the inspector is destroyed. Removes event listeners
+ * and cleans up references.
*/
- destroy: function () {
- this.chromeDoc = null;
- this.inspector.sidebar.off("fontinspector-selected", this.onNewNode);
+ destroy() {
this.inspector.selection.off("new-node-front", this.onNewNode);
- this.showAllLink.removeEventListener("click", this.showAll);
- this.previewInput.removeEventListener("input", this.previewTextChanged);
- this.previewInput.removeEventListener("contextmenu",
- this.inspector.onTextBoxContextMenu);
-
+ this.inspector.sidebar.off("fontinspector-selected", this.onNewNode);
gDevTools.off("theme-switched", this.onThemeChanged);
- if (this._previewUpdateTimeout) {
- clearTimeout(this._previewUpdateTimeout);
- }
+ this.document = null;
+ this.inspector = null;
+ this.pageStyle = null;
+ this.store = null;
+ },
+
+ /**
+ * Returns true if the font inspector panel is visible, and false otherwise.
+ */
+ isPanelVisible() {
+ return this.inspector.sidebar &&
+ this.inspector.sidebar.getCurrentTabID() === "fontinspector";
},
/**
* Selection 'new-node' event handler.
*/
- onNewNode: function () {
- if (this.isActive() &&
- this.inspector.selection.isConnected() &&
- this.inspector.selection.isElementNode()) {
- this.undim();
+ onNewNode() {
+ if (this.isPanelVisible()) {
+ this.update(false);
+ }
+ },
+
+ /**
+ * Handler for the "theme-switched" event.
+ */
+ onThemeChanged(event, frame) {
+ if (frame === this.document.defaultView) {
this.update();
- } else {
- this.dim();
}
},
/**
- * The text to use for previews. Returns either the value user has typed to
- * the preview input or DEFAULT_PREVIEW_TEXT if the input is empty or contains
- * only whitespace.
- */
- getPreviewText: function () {
- let inputText = this.previewInput.value.trim();
- if (inputText === "") {
- return DEFAULT_PREVIEW_TEXT;
- }
-
- return inputText;
- },
-
- /**
- * Preview input 'input' event handler.
+ * Handler for change in preview input.
*/
- previewTextChanged: function () {
- if (this._previewUpdateTimeout) {
- clearTimeout(this._previewUpdateTimeout);
- }
-
- this._previewUpdateTimeout = setTimeout(() => {
- this.update(this._lastUpdateShowedAllFonts);
- }, PREVIEW_UPDATE_DELAY);
- },
-
- /**
- * Callback for the theme-switched event.
- */
- onThemeChanged: function (event, frame) {
- if (frame === this.chromeDoc.defaultView) {
- this.update(this._lastUpdateShowedAllFonts);
- }
+ onPreviewFonts(value) {
+ this.update(undefined, value);
},
/**
- * Hide the font list. No node are selected.
+ * Handler for click on show all fonts button.
*/
- dim: function () {
- let panel = this.chromeDoc.getElementById("sidebar-panel-fontinspector");
- panel.classList.add("dim");
- this.clear();
- },
-
- /**
- * Show the font list. A node is selected.
- */
- undim: function () {
- let panel = this.chromeDoc.getElementById("sidebar-panel-fontinspector");
- panel.classList.remove("dim");
+ onShowAllFontClick() {
+ this.update(true);
},
- /**
- * Clears the font list.
- */
- clear: function () {
- this.chromeDoc.querySelector("#all-fonts").innerHTML = "";
- },
-
- /**
- * Retrieve all the font info for the selected node and display it.
- */
- update: Task.async(function* (showAllFonts) {
+ update: Task.async(function* (showAllFonts = this.store.getState().showAllFonts,
+ previewText = this.store.getState().previewText) {
let node = this.inspector.selection.nodeFront;
- let panel = this.chromeDoc.getElementById("sidebar-panel-fontinspector");
if (!node ||
- !this.isActive() ||
+ !this.isPanelVisible() ||
!this.inspector.selection.isConnected() ||
- !this.inspector.selection.isElementNode() ||
- panel.classList.contains("dim")) {
+ !this.inspector.selection.isElementNode()) {
return;
}
- this._lastUpdateShowedAllFonts = showAllFonts;
+ this.store.dispatch(updatePreviewText(previewText));
+ this.store.dispatch(updateShowAllFonts(showAllFonts));
let options = {
includePreviews: true,
- previewText: this.getPreviewText(),
+ previewText: (previewText === "") ? DEFAULT_PREVIEW_TEXT : previewText,
previewFillStyle: getColor("body-color")
};
let fonts = [];
if (showAllFonts) {
fonts = yield this.pageStyle.getAllUsedFontFaces(options)
.then(null, console.error);
} else {
fonts = yield this.pageStyle.getUsedFontFaces(node, options)
.then(null, console.error);
}
if (!fonts || !fonts.length) {
// No fonts to display. Clear the previously shown fonts.
- this.clear();
+ this.store.dispatch(updateFonts(fonts));
return;
}
for (let font of fonts) {
font.previewUrl = yield font.preview.data.string();
}
// in case we've been destroyed in the meantime
- if (!this.chromeDoc) {
+ if (!this.document) {
return;
}
- // Make room for the new fonts.
- this.clear();
-
- for (let font of fonts) {
- this.render(font);
- }
+ this.store.dispatch(updateFonts(fonts));
this.inspector.emit("fontinspector-updated");
- }),
-
- /**
- * Display the information of one font.
- */
- render: function (font) {
- let s = this.chromeDoc.querySelector("#font-template > section");
- s = s.cloneNode(true);
-
- s.querySelector(".font-name").textContent = font.name;
- s.querySelector(".font-css-name").textContent = font.CSSFamilyName;
-
- if (font.URI) {
- s.classList.add("is-remote");
- } else {
- s.classList.add("is-local");
- }
-
- let formatElem = s.querySelector(".font-format");
- if (font.format) {
- formatElem.textContent = font.format;
- } else {
- formatElem.hidden = true;
- }
-
- s.querySelector(".font-url").value = font.URI;
-
- if (font.rule) {
- // This is the @font-face{…} code.
- let cssText = font.ruleText;
-
- s.classList.add("has-code");
- s.querySelector(".font-css-code").textContent = cssText;
- }
- let preview = s.querySelector(".font-preview");
- preview.src = font.previewUrl;
-
- this.chromeDoc.querySelector("#all-fonts").appendChild(s);
- },
-
- /**
- * Show all fonts for the document (including iframes)
- */
- showAll: function () {
- this.update(true);
- },
+ })
};
-exports.FontInspector = FontInspector;
+module.exports = FontInspector;
--- a/devtools/client/inspector/fonts/moz.build
+++ b/devtools/client/inspector/fonts/moz.build
@@ -1,11 +1,19 @@
# -*- Mode: python; 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/.
+DIRS += [
+ 'actions',
+ 'components',
+ 'reducers',
+ 'utils',
+]
+
DevToolsModules(
'fonts.js',
+ 'types.js',
)
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/reducers/fonts.js
@@ -0,0 +1,27 @@
+/* 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 {
+ UPDATE_FONTS,
+} = require("../actions/index");
+
+const INITIAL_FONTS = [];
+
+let reducers = {
+
+ [UPDATE_FONTS](_, { fonts }) {
+ return fonts;
+ },
+
+};
+
+module.exports = function (fonts = INITIAL_FONTS, action) {
+ let reducer = reducers[action.type];
+ if (!reducer) {
+ return fonts;
+ }
+ return reducer(fonts, action);
+};
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/reducers/moz.build
@@ -0,0 +1,11 @@
+# -*- Mode: python; 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(
+ 'fonts.js',
+ 'preview-text.js',
+ 'show-all-fonts.js',
+)
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/reducers/preview-text.js
@@ -0,0 +1,27 @@
+/* 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 {
+ UPDATE_PREVIEW_TEXT,
+} = require("../actions/index");
+
+const INITIAL_PREVIEW_TEXT = "";
+
+let reducers = {
+
+ [UPDATE_PREVIEW_TEXT](_, { previewText }) {
+ return previewText;
+ },
+
+};
+
+module.exports = function (previewText = INITIAL_PREVIEW_TEXT, action) {
+ let reducer = reducers[action.type];
+ if (!reducer) {
+ return previewText;
+ }
+ return reducer(previewText, action);
+};
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/reducers/show-all-fonts.js
@@ -0,0 +1,27 @@
+/* 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 {
+ UPDATE_SHOW_ALL_FONTS,
+} = require("../actions/index");
+
+const INITIAL_SHOW_ALL_FONTS = false;
+
+let reducers = {
+
+ [UPDATE_SHOW_ALL_FONTS](_, { showAllFonts }) {
+ return showAllFonts;
+ },
+
+};
+
+module.exports = function (showAllFonts = INITIAL_SHOW_ALL_FONTS, action) {
+ let reducer = reducers[action.type];
+ if (!reducer) {
+ return showAllFonts;
+ }
+ return reducer(showAllFonts, action);
+};
--- a/devtools/client/inspector/fonts/test/browser_fontinspector.js
+++ b/devtools/client/inspector/fonts/test/browser_fontinspector.js
@@ -31,17 +31,17 @@ const FONTS = [{
format: "",
cssName: "barnormal"
}];
add_task(function* () {
let { inspector, view } = yield openFontInspectorForURL(TEST_URI);
ok(!!view, "Font inspector document is alive.");
- let viewDoc = view.chromeDoc;
+ let viewDoc = view.document;
yield testBodyFonts(inspector, viewDoc);
yield testDivFonts(inspector, viewDoc);
yield testShowAllFonts(inspector, viewDoc);
});
function* testBodyFonts(inspector, viewDoc) {
let s = viewDoc.querySelectorAll("#all-fonts > section");
--- a/devtools/client/inspector/fonts/test/browser_fontinspector_edit-previews-show-all.js
+++ b/devtools/client/inspector/fonts/test/browser_fontinspector_edit-previews-show-all.js
@@ -5,17 +5,17 @@
// Test that correct previews are shown if the text is edited after 'Show all'
// button is pressed.
const TEST_URI = URL_ROOT + "browser_fontinspector.html";
add_task(function* () {
let { inspector, view } = yield openFontInspectorForURL(TEST_URI);
- let viewDoc = view.chromeDoc;
+ let viewDoc = view.document;
info("Selecting a node that doesn't contain all document fonts.");
yield selectNode(".normal-text", inspector);
let normalTextNumPreviews =
viewDoc.querySelectorAll("#all-fonts .font-preview").length;
let onUpdated = inspector.once("fontinspector-updated");
--- a/devtools/client/inspector/fonts/test/browser_fontinspector_edit-previews.js
+++ b/devtools/client/inspector/fonts/test/browser_fontinspector_edit-previews.js
@@ -6,17 +6,17 @@
// Test that previews change when the preview text changes. It doesn't check the
// exact preview images because they are drawn on a canvas causing them to vary
// between systems, platforms and software versions.
const TEST_URI = URL_ROOT + "browser_fontinspector.html";
add_task(function* () {
let {view} = yield openFontInspectorForURL(TEST_URI);
- let viewDoc = view.chromeDoc;
+ let viewDoc = view.document;
let previews = viewDoc.querySelectorAll("#all-fonts .font-preview");
let initialPreviews = [...previews].map(p => p.src);
info("Typing 'Abc' to check that the reference previews are correct.");
yield updatePreviewText(view, "Abc");
checkPreviewImages(viewDoc, initialPreviews, true);
--- a/devtools/client/inspector/fonts/test/browser_fontinspector_theme-change.js
+++ b/devtools/client/inspector/fonts/test/browser_fontinspector_theme-change.js
@@ -14,17 +14,17 @@ const originalTheme = getTheme();
registerCleanupFunction(() => {
info(`Restoring theme to '${originalTheme}.`);
setTheme(originalTheme);
});
add_task(function* () {
let { inspector, view } = yield openFontInspectorForURL(TEST_URI);
- let { chromeDoc: doc } = view;
+ let { document: doc } = view;
yield selectNode(".normal-text", inspector);
// Store the original preview URI for later comparison.
let originalURI = doc.querySelector("#all-fonts .font-preview").src;
let newTheme = originalTheme === "light" ? "dark" : "light";
info(`Original theme was '${originalTheme}'.`);
--- a/devtools/client/inspector/fonts/test/head.js
+++ b/devtools/client/inspector/fonts/test/head.js
@@ -56,18 +56,18 @@ var openFontInspectorForURL = Task.async
* preview images to be updated.
*
* @param {FontInspector} view - The FontInspector instance.
* @param {String} text - The text to preview.
*/
function* updatePreviewText(view, text) {
info(`Changing the preview text to '${text}'`);
- let doc = view.chromeDoc;
- let input = doc.getElementById("font-preview-text-input");
+ let doc = view.document;
+ let input = doc.querySelector("#sidebar-panel-fontinspector .devtools-textinput");
let update = view.inspector.once("fontinspector-updated");
info("Focusing the input field.");
input.focus();
is(doc.activeElement, input, "The input was focused.");
info("Blanking the input field.");
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/types.js
@@ -0,0 +1,35 @@
+/* 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 { PropTypes } = require("devtools/client/shared/vendor/react");
+
+/**
+ * A single font.
+ */
+exports.font = {
+
+ // The name of the font
+ name: PropTypes.string,
+
+ // The name of the font family
+ cssFamilyName: PropTypes.string,
+
+ // The format of the font
+ format: PropTypes.string,
+
+ // The URI of the font file
+ URI: PropTypes.string,
+
+ // Object containing the CSS rule for the font
+ rule: PropTypes.object,
+
+ // The text of the CSS rule
+ ruleText: PropTypes.string,
+
+ // URL for the font preview
+ previewUrl: PropTypes.string,
+
+};
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/utils/l10n.js
@@ -0,0 +1,15 @@
+/* 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 { LocalizationHelper } = require("devtools/shared/l10n");
+const L10N = new LocalizationHelper("devtools/client/locales/font-inspector.properties");
+
+module.exports = {
+ getStr: (...args) => L10N.getStr(...args),
+ getFormatStr: (...args) => L10N.getFormatStr(...args),
+ getFormatStrWithNumbers: (...args) => L10N.getFormatStrWithNumbers(...args),
+ numberWithDecimals: (...args) => L10N.numberWithDecimals(...args),
+};
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/fonts/utils/moz.build
@@ -0,0 +1,9 @@
+# -*- Mode: python; 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(
+ 'l10n.js',
+)
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -572,17 +572,17 @@ Inspector.prototype = {
break;
case "boxmodel":
// box-model isn't a panel on its own, it used to, now it is being used by
// computed view and layout which retrieves an instance via getPanel.
const BoxModel = require("devtools/client/inspector/boxmodel/box-model");
panel = new BoxModel(this, this.panelWin);
break;
case "fontinspector":
- const {FontInspector} = require("devtools/client/inspector/fonts/fonts");
+ const FontInspector = require("devtools/client/inspector/fonts/fonts");
panel = new FontInspector(this, this.panelWin);
break;
default:
// This is a custom panel or a non lazy-loaded one.
return null;
}
this._panels.set(id, panel);
return panel;
@@ -630,20 +630,19 @@ Inspector.prototype = {
"animationinspector",
INSPECTOR_L10N.getStr("inspector.sidebar.animationInspectorTitle"),
"chrome://devtools/content/animationinspector/animation-inspector.xhtml",
defaultTab == "animationinspector");
}
if (Services.prefs.getBoolPref("devtools.fontinspector.enabled") &&
this.canGetUsedFontFaces) {
- this.sidebar.addExistingTab(
- "fontinspector",
- INSPECTOR_L10N.getStr("inspector.sidebar.fontInspectorTitle"),
- defaultTab == "fontinspector");
+ const FontInspector = this.browserRequire("devtools/client/inspector/fonts/fonts");
+ this.fontinspector = new FontInspector(this, this.panelWin);
+ this.fontinspector.init();
this.sidebar.toggleTab(true, "fontinspector");
}
// Setup the splitter before the sidebar is displayed so,
// we don't miss any events.
this.setupSplitter();
@@ -970,16 +969,20 @@ Inspector.prototype = {
if (this.gridInspector) {
this.gridInspector.destroy();
}
if (this.layoutview) {
this.layoutview.destroy();
}
+ if (this.fontinspector) {
+ this.fontinspector.destroy();
+ }
+
let cssPropertiesDestroyer = this._cssPropertiesLoaded.then(({front}) => {
if (front) {
front.destroy();
}
});
this.sidebar.off("select", this.onSidebarSelect);
let sidebarDestroyer = this.sidebar.destroy();
--- a/devtools/client/inspector/inspector.xhtml
+++ b/devtools/client/inspector/inspector.xhtml
@@ -140,54 +140,16 @@
<div id="propertyContainer" class="theme-separator" tabindex="0" dir="ltr">
</div>
<div id="computedview-no-results" hidden="" data-localization="content=inspector.noProperties"></div>
</div>
</div>
</div>
- <div id="sidebar-panel-fontinspector" class="devtools-monospace theme-sidebar inspector-tabpanel"
- data-localization-bundle="devtools/client/locales/font-inspector.properties">
- <div class="devtools-toolbar">
- <div class="devtools-searchbox">
- <input id="font-preview-text-input" class="devtools-textinput" type="search"
- data-localization="placeholder=fontinspector.previewText"/>
- </div>
- <label id="font-showall" class="theme-link"
- data-localization="content=fontinspector.seeAll;
- title=fontinspector.seeAll.tooltip"></label>
- </div>
-
- <div id="font-container">
- <ul id="all-fonts"></ul>
- </div>
-
- <div id="font-template">
- <section class="font">
- <div class="font-preview-container">
- <img class="font-preview"></img>
- </div>
- <div class="font-info">
- <h1 class="font-name"></h1>
- <span class="font-is-local" data-localization="content=fontinspector.system"></span>
- <span class="font-is-remote" data-localization="content=fontinspector.remote"></span>
- <p class="font-format-url">
- <input readonly="readonly" class="font-url"></input>
- <span class="font-format"></span>
- </p>
- <p class="font-css">
- <span data-localization="content=fontinspector.usedAs"></span> "<span class="font-css-name"></span>"
- </p>
- <pre class="font-css-code"></pre>
- </div>
- </section>
- </div>
- </div>
-
<div id="sidebar-panel-animationinspector" class="devtools-monospace theme-sidebar inspector-tabpanel">
<iframe class="devtools-inspector-tab-frame"></iframe>
</div>
</div>
</div>
</body>
</html>
--- a/devtools/client/inspector/reducers.js
+++ b/devtools/client/inspector/reducers.js
@@ -3,10 +3,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
// This file exposes the Redux reducers of the box model, grid and grid highlighter
// settings.
exports.boxModel = require("devtools/client/inspector/boxmodel/reducers/box-model");
+exports.fonts = require("devtools/client/inspector/fonts/reducers/fonts");
exports.grids = require("devtools/client/inspector/grids/reducers/grids");
exports.highlighterSettings = require("devtools/client/inspector/grids/reducers/highlighter-settings");
+exports.previewText = require("devtools/client/inspector/fonts/reducers/preview-text");
+exports.showAllFonts = require("devtools/client/inspector/fonts/reducers/show-all-fonts");
--- a/devtools/client/shared/browser-loader.js
+++ b/devtools/client/shared/browser-loader.js
@@ -9,16 +9,17 @@ const { devtools } = Cu.import("resource
const { joinURI } = devtools.require("devtools/shared/path");
const { assert } = devtools.require("devtools/shared/DevToolsUtils");
const Services = devtools.require("Services");
const { AppConstants } = devtools.require("resource://gre/modules/AppConstants.jsm");
const BROWSER_BASED_DIRS = [
"resource://devtools/client/inspector/boxmodel",
"resource://devtools/client/inspector/computed",
+ "resource://devtools/client/inspector/fonts",
"resource://devtools/client/inspector/grids",
"resource://devtools/client/inspector/layout",
"resource://devtools/client/jsonview",
"resource://devtools/client/shared/source-map",
"resource://devtools/client/shared/redux",
"resource://devtools/client/shared/vendor",
];