Przeglądaj źródła

added single debug flag to IconRegistry

telamonian 5 lat temu
rodzic
commit
1d384f5285

+ 1 - 3
packages/application/src/shell.ts

@@ -179,8 +179,7 @@ export class LabShell extends Widget implements JupyterFrontEnd.IShell {
     let topPanel = (this._topPanel = new Panel());
     let hboxPanel = new BoxPanel();
     let dockPanel = (this._dockPanel = new DockPanelSvg({
-      kind: 'dockPanelBar',
-      skipbad: true
+      kind: 'dockPanelBar'
     }));
     let headerPanel = (this._headerPanel = new Panel());
     MessageLoop.installMessageHook(dockPanel, this._dockChildHook);
@@ -1035,7 +1034,6 @@ namespace Private {
     constructor(side: string) {
       this._sideBar = new TabBarSvg<Widget>({
         kind: 'sideBar',
-        skipbad: true,
         insertBehavior: 'none',
         removeBehavior: 'none',
         allowDeselect: true

+ 21 - 21
packages/ui-components/src/icon/icon.ts

@@ -27,30 +27,30 @@ import folderSvg from '../../style/icons/sidebar/folder.svg'; // originally ic-f
 import paletteSvg from '../../style/icons/sidebar/palette.svg'; // originally ic-palette-24px.svg
 import runningSvg from '../../style/icons/sidebar/running.svg'; // originally stop-circle.svg
 import tabSvg from '../../style/icons/sidebar/tab.svg'; // originally ic-tab-24px.svg
-
-export const defaultIcons: ReadonlyArray<Icon.IModel> = [
-  { name: 'jupyter-favicon', svg: jupyterFaviconSvg },
-
-  { name: 'html5', svg: html5Svg },
-  { name: 'react', svg: reactSvg },
-
-  { name: 'kernel', svg: kernelSvg },
-  { name: 'line-form', svg: lineFormSvg },
-  { name: 'not-trusted', svg: notTrustedSvg },
-  { name: 'status-bar', svg: statusBarSvg },
-  { name: 'terminal', svg: terminalSvg },
-  { name: 'trusted', svg: trustedSvg },
-
-  { name: 'build', svg: buildSvg },
-  { name: 'extension', svg: extensionSvg },
-  { name: 'folder', svg: folderSvg },
-  { name: 'palette', svg: paletteSvg },
-  { name: 'running', svg: runningSvg },
-  { name: 'tab', svg: tabSvg }
-];
 /* tslint:enable */
 
 export namespace Icon {
+  export const defaultIcons: ReadonlyArray<IModel> = [
+    { name: 'jupyter-favicon', svg: jupyterFaviconSvg },
+
+    { name: 'html5', svg: html5Svg },
+    { name: 'react', svg: reactSvg },
+
+    { name: 'kernel', svg: kernelSvg },
+    { name: 'line-form', svg: lineFormSvg },
+    { name: 'not-trusted', svg: notTrustedSvg },
+    { name: 'status-bar', svg: statusBarSvg },
+    { name: 'terminal', svg: terminalSvg },
+    { name: 'trusted', svg: trustedSvg },
+
+    { name: 'build', svg: buildSvg },
+    { name: 'extension', svg: extensionSvg },
+    { name: 'folder', svg: folderSvg },
+    { name: 'palette', svg: paletteSvg },
+    { name: 'running', svg: runningSvg },
+    { name: 'tab', svg: tabSvg }
+  ];
+
   export interface IModel {
     name: string;
     className?: string;

+ 54 - 30
packages/ui-components/src/icon/iconregistry.tsx

@@ -4,7 +4,7 @@
 import React from 'react';
 import { classes } from 'typestyle/lib';
 
-import { Icon, defaultIcons } from './icon';
+import { Icon } from './icon';
 import { camelize } from '../utils';
 import { IIconStyle, iconStyle, iconStyleFlat } from '../style/icon';
 
@@ -14,12 +14,11 @@ import badSvg from '../../style/icons/bad.svg';
  * The icon registry class.
  */
 export class IconRegistry {
-  constructor(...icons: Icon.IModel[]) {
-    if (icons.length) {
-      this.addIcon(...icons);
-    } else {
-      this.addIcon(...defaultIcons);
-    }
+  constructor(options?: IconRegistry.IOptions) {
+    this._debug = !!options.debug;
+
+    let icons = options.initialIcons || Icon.defaultIcons;
+    this.addIcon(...icons);
 
     // add the bad state icon
     this.addIcon({ name: 'bad', svg: badSvg });
@@ -36,31 +35,16 @@ export class IconRegistry {
     });
   }
 
-  resolveName(name: string): string {
-    if (!(name in this._svg)) {
-      // assume name is really a className, split the className into parts and check each part
-      for (let className of name.split(/\s+/)) {
-        if (className in this._classNameToName) {
-          return this._classNameToName[className];
-        }
-      }
-      // couldn't resolve name, mark as bad
-      return 'bad';
-    }
-
-    return name;
-  }
-
   /**
    * Get the icon as an HTMLElement of tag <svg><svg/>
    */
   icon(
     props: IconRegistry.IIconOptions & { container: HTMLElement } & IIconStyle
   ): HTMLElement {
-    const { name, className, title, skipbad, container, ...propsStyle } = props;
+    const { name, className, title, container, ...propsStyle } = props;
 
     // if name not in _svg, assume we've been handed a className in place of name
-    let svg = this.svg(name, skipbad);
+    let svg = this.resolveSvg(name);
     if (!svg) {
       // bail
       return;
@@ -78,7 +62,7 @@ export class IconRegistry {
       container.appendChild(svgNode);
 
       let styleClass = propsStyle ? iconStyle(propsStyle) : '';
-      if (className) {
+      if (className || className === '') {
         // override the className, if explicitly passed
         container.className = classes(className, styleClass);
       } else if (!(styleClass in container.classList)) {
@@ -103,10 +87,10 @@ export class IconRegistry {
   iconReact(
     props: IconRegistry.IIconOptions & { tag?: 'div' | 'span' } & IIconStyle
   ): React.ReactElement {
-    const { name, className, title, skipbad, tag, ...propsStyle } = props;
+    const { name, className, title, tag, ...propsStyle } = props;
     const Tag = tag || 'div';
 
-    let svg = this.svg(name, skipbad);
+    let svg = this.resolveSvg(name);
     if (!svg) {
       // bail
       return;
@@ -120,11 +104,26 @@ export class IconRegistry {
     );
   }
 
-  svg(name: string, skipbad: boolean = false): string {
+  resolveName(name: string): string {
+    if (!(name in this._svg)) {
+      // assume name is really a className, split the className into parts and check each part
+      for (let className of name.split(/\s+/)) {
+        if (className in this._classNameToName) {
+          return this._classNameToName[className];
+        }
+      }
+      // couldn't resolve name, mark as bad
+      return 'bad';
+    }
+
+    return name;
+  }
+
+  resolveSvg(name: string): string {
     let svgname = this.resolveName(name);
 
     if (svgname === 'bad') {
-      if (!skipbad) {
+      if (this._debug) {
         // log a warning and mark missing icons with an X
         console.error(`Invalid icon name: ${name}`);
       } else {
@@ -136,11 +135,16 @@ export class IconRegistry {
     return this._svg[svgname];
   }
 
+  get svg() {
+    return this._svg;
+  }
+
   static iconClassName(name: string): string {
     return 'jp-' + camelize(name, true) + 'Icon';
   }
 
   private _classNameToName: { [key: string]: string } = Object.create(null);
+  private _debug: boolean = false;
   private _nameToClassName: { [key: string]: string } = Object.create(null);
   private _svg: { [key: string]: string } = Object.create(null);
 }
@@ -160,11 +164,31 @@ export const IconReact = (
 };
 
 export namespace IconRegistry {
+  /**
+   * The options used to create an icon registry.
+   */
+  export interface IOptions {
+    /**
+     * The initial icons for the registry.
+     * The [[Icon.defaultIcons]] will be used if not given.
+     */
+    initialIcons?: Icon.IModel[];
+
+    /**
+     * If the debug flag is set, missing icons will raise a warning
+     * and be visually marked with an "X". Otherwise, missing icons
+     * will fail silently.
+     */
+    debug?: boolean;
+  }
+
+  /**
+   * The options used to set an icon
+   */
   export interface IIconOptions {
     name: string;
     className?: string;
     title?: string;
-    skipbad?: boolean;
   }
 }
 

+ 7 - 11
packages/ui-components/src/icon/tabbarsvg.ts

@@ -18,14 +18,11 @@ export class TabBarSvg<T> extends TabBar<T> {
    *
    * @param options - The options for initializing the tab bar.
    */
-  constructor(
-    options: { kind: IconKindType; skipbad?: boolean } & TabBar.IOptions<T>
-  ) {
+  constructor(options: TabBarSvg.IOptions<T>) {
     options.renderer = options.renderer || TabBarSvg.defaultRenderer;
     super(options);
 
     this._kind = options.kind;
-    this._skipbad = options.skipbad;
   }
 
   /**
@@ -46,18 +43,20 @@ export class TabBarSvg<T> extends TabBar<T> {
           name: title.iconClass,
           container: iconNode,
           center: true,
-          kind: this._kind,
-          skipbad: this._skipbad
+          kind: this._kind
         });
       }
     }
   }
 
   protected _kind: IconKindType;
-  protected _skipbad: boolean;
 }
 
 export namespace TabBarSvg {
+  export interface IOptions<T> extends TabBar.IOptions<T> {
+    kind: IconKindType;
+  }
+
   /**
    * A modified implementation of the TabBar Renderer.
    */
@@ -97,7 +96,6 @@ export class DockPanelSvg extends DockPanel {
       // can't add a constructor to Renderer, so have to set properties here
       let renderer = new DockPanelSvg.Renderer();
       renderer._kind = options.kind || renderer._kind;
-      renderer._skipbad = options.skipbad || renderer._skipbad;
       options.renderer = renderer;
     }
 
@@ -118,14 +116,12 @@ export namespace DockPanelSvg {
      */
     createTabBar(): TabBarSvg<Widget> {
       let bar = new TabBarSvg<Widget>({
-        kind: this._kind,
-        skipbad: this._skipbad
+        kind: this._kind
       });
       bar.addClass('p-DockPanel-tabBar');
       return bar;
     }
 
     _kind: IconKindType = 'dockPanelBar';
-    _skipbad: boolean = false;
   }
 }