浏览代码

Update the faq extension

Steven Silvester 7 年之前
父节点
当前提交
d0405f26b0
共有 3 个文件被更改,包括 145 次插入548 次删除
  1. 145 17
      packages/faq-extension/src/index.ts
  2. 0 409
      packages/faq-extension/src/widget.ts
  3. 0 122
      packages/faq-extension/style/index.css

+ 145 - 17
packages/faq-extension/src/index.ts

@@ -14,11 +14,12 @@ import {
 } from '@phosphor/coreutils';
 
 import {
-  FaqModel, FaqWidget
-} from './widget';
+  Widget
+} from '@phosphor/widgets';
 
 import '../style/index.css';
 
+
 /**
  * The command IDs used by the FAQ plugin.
  */
@@ -45,15 +46,133 @@ const plugin: JupyterLabPlugin<void> = {
 export default plugin;
 
 
+/**
+ * The faq page source.
+ */
+const SOURCE = `
+## General
+* [What is JupyterLab?](#What-is-JupyterLab?)
+* [What new features does JupyterLab offer?](#What-new-features-does-JupyterLab-offer?)
+* [How stable is JupyterLab?](#How-stable-is-JupyterLab?)
+* [What will happen to the classic Jupyter Notebook?](#What-will-happen-to-the-classic-Jupyter-Notebook?)
+* [Where is the documentation for JupyterLab?](#Where-is-the-documentation-for-JupyterLab?)
+
+## Development
+
+* [How do I report a bug or provide feedback?](#How-do-I-report-a-bug-or-provide-feedback?)
+* [How can I contribute?](#How-can-I-contribute?)
+* [How can I extend or customize JupyterLab?](#How-can-I-extend-or-customize-JupyterLab?)
+
+## General
+
+### What is JupyterLab?
+
+JupyterLab is a new user interface for the Jupyter Notebook, allowing
+users to arrange multiple Jupyter notebooks, text editors, terminals,
+output areas, etc. on a single page with multiple panels and tabs in
+one integrated application. The codebase and user-interface of JupyterLab
+is based on a flexible extension system that makes it easy to extend with new
+functionality.
+
+### What new features does JupyterLab offer?
+
+JupyterLab offers a number of features beyond the classic Jupyter
+Notebook. Here are a few of them you may want to try out:
+
+* Arrange multiple notebooks, terminals, text files, etc. in the
+  application using drag and drop.
+* Run code interactively outside of a notebook in the Code Console,
+  and connect one  to a text file.
+* Right click on a markdown file and "Open with..." a live markdown
+  viewer.
+* Double click on CSV files to view them as a nicely formatted table.
+* Drag and drop notebook cells within a notebook or between notebooks.
+
+### How stable is JupyterLab?
+
+We are currently making a series of alpha releases of JupyterLab.
+These releases are mostly usable, but you may
+experience bugs and other rough edges as the code base is still
+changing rapidly.
+
+In June 2017, we will be releasing a beta version. This beta
+version will be characterized by:
+
+* Stable and featureful enough for daily usage by most Jupyter users.
+* Most of the commonly used features in the classic notebook are
+  implemented.
+* Developer APIs that are approaching stability but stil undergoing
+  significant changes.
+
+Later in 2017, we will release the 1.0 version of JupyterLab that will
+provide additional UI/UX improvements, features, and API stability. At
+that point, JupyterLab should be a full featured replacement for the
+classic notebook - and go far beyond its capabilities.
+
+### What will happen to the classic Jupyter Notebook?
+
+JupyterLab is intended to be a full replacement for the classic Jupyter
+Notebook. Because of this, our plan is to gradually retire the classic
+Jupyter Notebook. However, we will support the classic notebook for a
+signifciant period of time to help users and extension authors through
+this transition. It is important to note that the notebook server
+and the notebook document format is unchanged during this transition.
+
+### Where is the documentation for JupyterLab?
+
+The documentation for JupyterLab can be found on ReadTheDocs [here](http://jupyterlab.readthedocs.io/en/latest/).
+
+## Development
+
+### How do I report a bug or provide feedback?
+
+If you find a bug or want to provide feedback, please open an issue
+on our [GitHub Issues page](https://github.com/jupyterlab/jupyterlab/issues).
+
+### How can I contribute?
+
+We welcome other developers and designers to contribute to JupyterLab.
+Development of JupyterLab takes place on our [GitHub Repository](https://github.com/jupyterlab/jupyterlab).
+To get started with development, please have a look at our
+[Contributing Guide](https://github.com/jupyterlab/jupyterlab/blob/master/CONTRIBUTING.md)
+or chat with us on our [Gitter Channel](https://gitter.im/jupyterlab/jupyterlab).
+
+JupyterLab is a
+part of Project Jupyter and follows the [Jupyter Code of Conduct](https://github.com/jupyter/governance/blob/master/conduct/code_of_conduct.md).
+
+### How can I extend or customize JupyterLab?
+
+JupyterLab consists entirely of *JupyterLab Extensions*, which are simply
+[NPM](https://www.npmjs.com/) packages that utilize the public JupyterLab
+APIs. You can develop your own custom extensions that use these APIs to
+extend the functionality of JupyterLab. Examples of possible extensions include:
+
+* Custom renderers/viewers/editors for specific file types.
+* Renderers for custom output types in the notebook.
+* Entirely new user interfaces for working with data that utilize
+  JupyterLab's layout, command palette and integrate in various ways
+  with our core extensions (notebooks, code consoles, etc.).
+
+To start developing your own JupyterLab extension, please have a look
+at:
+
+* [JupyterLab Documentation](http://jupyterlab.readthedocs.io/en/latest/)
+* JupyterLab Extension Template for [TypeScript](Cookiecutters(https://github.com/jupyterlab/extension-cookiecutter-ts)
+* JupyterLab Extension Template for [JavaScript](https://github.com/jupyterlab/extension-cookiecutter-js)
+`;
+
+
 /**
  * Activate the FAQ plugin.
  */
 function activate(app: JupyterLab, palette: ICommandPalette, restorer: ILayoutRestorer): void {
   const category = 'Help';
   const command = CommandIDs.open;
-  const model = new FaqModel();
-  const { commands, shell } = app;
-  const tracker = new InstanceTracker<FaqWidget>({ namespace: 'faq' });
+  const { commands, shell, rendermime } = app;
+  const tracker = new InstanceTracker<Widget>({
+    namespace: 'faq',
+    disposeOnDetach: true
+  });
 
   // Handle state restoration.
   restorer.restore(tracker, {
@@ -62,23 +181,32 @@ function activate(app: JupyterLab, palette: ICommandPalette, restorer: ILayoutRe
     name: () => 'faq'
   });
 
-  let widget: FaqWidget;
+  let createWidget = () => {
+    let renderer = rendermime.createRenderer('text/markdown');
+    renderer.id = 'faq';
+    renderer.addClass('jp-FAQ');
+    renderer.title.label = 'FAQ';
+    renderer.title.closable = true;
+    renderer.node.tabIndex = -1;
+
+    const model = rendermime.createModel({
+      data: { 'text/markdown': SOURCE }
+    });
+    renderer.renderModel(model);
 
-  function newWidget(): FaqWidget {
-    let widget = new FaqWidget({ linker: app.commandLinker });
-    widget.model = model;
-    widget.id = 'faq';
-    widget.title.label = 'FAQ';
-    widget.title.closable = true;
-    tracker.add(widget);
-    return widget;
-  }
+    return renderer;
+  };
+
+  let widget = createWidget();
 
   commands.addCommand(command, {
     label: 'Open FAQ',
     execute: () => {
-      if (!widget || widget.isDisposed) {
-        widget = newWidget();
+      if (widget.isDisposed) {
+        widget = createWidget();
+      }
+      if (!tracker.has(widget)) {
+        tracker.add(widget);
         shell.addToMainArea(widget);
       }
       shell.activateById(widget.id);

+ 0 - 409
packages/faq-extension/src/widget.ts

@@ -1,409 +0,0 @@
-// Copyright (c) Jupyter Development Team.
-// Distributed under the terms of the Modified BSD License.
-
-import {
-  CommandLinker, VDomModel, VDomRenderer
-} from '@jupyterlab/apputils';
-
-import {
-  Message
-} from '@phosphor/messaging';
-
-import {
-  h, VirtualNode
-} from '@phosphor/virtualdom';
-
-
-/**
- * The class name added to the FAQ plugin.
- */
-const FAQ_CLASS = 'jp-FAQ';
-
-/**
- * The id name added to the header section element.
- */
-const HEADER_ID = 'faq-header';
-
-/**
- * The class name added to the title.
- */
-const TITLE_CLASS = 'jp-FAQ-title';
-
-/**
- * The class name added to h1 elements.
- */
-const HEADER_CLASS = 'jp-FAQ-h1';
-
-/**
- * The class name added to h2 elements.
- */
-const SUBHEADER_CLASS = 'jp-FAQ-h2';
-
-/**
- * The class name added for the question mark icon from default-theme.
- */
-const QUESTIONMARK_ICON_CLASS = 'jp-QuestionMarkIcon';
-
-/**
- * The class named added the question mark icon.
- */
-const QUESTIONMARK_CLASS = 'jp-FAQ-QuestionMark';
-
-/**
- * The class name added to faq content.
- */
-const CONTENT_CLASS = 'jp-FAQ-content';
-
-/**
- * The class name added to unordered list elements.
- */
-const FAQ_LIST_CLASS = 'jp-FAQ-ul';
-
-/**
- * The class name added to table of contents elements.
- */
-const TOC_CLASS = 'jp-FAQ-toc';
-
-/**
- * The class name added to questions.
- */
-const QUESTION_CLASS = 'jp-FAQ-question';
-
-/**
- * The class name added to answers.
- */
-const ANSWER_CLASS = 'jp-FAQ-answer';
-
-/**
- * The class name added to anchor elements.
- */
-const ANCHOR_CLASS = 'jp-FAQ-a';
-
-/**
- * Title of the FAQ plugin.
- */
-const TITLE = 'Frequently Asked Questions';
-
-/**
- * Contain subheadings for each section.
- */
-const SUBHEADINGS = ['THE BASICS', 'FEATURES', 'DEVELOPER'];
-
-/**
- * Contain questions for `the basics` section.
- */
-const BASIC_QUESTIONS = [
-  'What is JupyterLab?',
-  'What is a Jupyter Notebook?',
-  'How stable is JupyterLab?',
-  `I'm confused with the interface. How do I navigate around JupyterLab?`
-];
-
-/**
- * Contain questions for the `features` section.
- */
-const FEATURES_QUESTIONS = [
-  'How do I add more kernels/languages to JupyterLab?',
-  'How can I share my notebooks?'
-];
-
-/**
- * Contain questions for the `developer` section.
- */
-const DEVELOPER_QUESTIONS = [
-  'How do I report a bug?',
-  'I have security concerns about JupyterLab.',
-  'How can I contribute?'
-];
-
-
-/**
- * FaqModel holds data which the FaqWidget will render.
- */
-export
-class FaqModel extends VDomModel {
-  /**
-   * Title of the FAQ plugin.
-   */
-  readonly title = TITLE;
-
-  /**
-   * Contain subheadings for each section.
-   */
-  readonly subheadings = SUBHEADINGS;
-
-  /**
-   * Contain questions for `the basics` section.
-   */
-  readonly basicsQuestions = BASIC_QUESTIONS;
-
-  /**
-   * Contain questions for the `features` section.
-   */
-  readonly featuresQuestions = FEATURES_QUESTIONS;
-
-  /**
-   * Contain questions for the `developer` section.
-   */
-  readonly developerQuestions = DEVELOPER_QUESTIONS;
-}
-
-/**
- * A virtual-DOM-based widget for the FAQ plugin.
- */
-export
-class FaqWidget extends VDomRenderer<FaqModel> {
-  /**
-   * Construct a new faq widget.
-   */
-  constructor(options: FaqWidget.IOptions) {
-    super();
-    this._linker = options.linker;
-    this.addClass(FAQ_CLASS);
-  }
-
-  /**
-   * Render the faq plugin to virtual DOM nodes.
-   */
-  protected render(): VirtualNode[] {
-    let model = this.model;
-    if (!model) {
-      return [];
-    }
-    let linker = this._linker;
-    let subheadings = model.subheadings;
-    let basicsQuestions = model.basicsQuestions;
-    let featuresQuestions = model.featuresQuestions;
-    let developerQuestions = model.developerQuestions;
-
-    // Create Frequently Asked Questions Header Section.
-    let faqHeader =
-    h.section({ id: HEADER_ID },
-      h.span({
-        className: QUESTIONMARK_ICON_CLASS + ' ' + QUESTIONMARK_CLASS
-      }),
-      h.h1({ className: HEADER_CLASS },
-        h.span({ className: TITLE_CLASS }, model.title)
-      )
-    );
-
-    // Create a section element that holds Table of Contents.
-    let questionList =
-    h.section({ className: CONTENT_CLASS },
-      h.h2({ className: SUBHEADER_CLASS }, subheadings[0]),
-      h.ul({ className: FAQ_LIST_CLASS },
-        h.li({ className: QUESTION_CLASS + ' ' + TOC_CLASS },
-          h.a({ href: '#basicsQ1' }, basicsQuestions[0])
-        ),
-        h.li({ className: QUESTION_CLASS + ' ' + TOC_CLASS },
-          h.a({ href: '#basicsQ2' }, basicsQuestions[1])
-        ),
-        h.li({ className: QUESTION_CLASS + ' ' + TOC_CLASS },
-          h.a({ href: '#basicsQ3' }, basicsQuestions[2])
-        ),
-        h.li({ className: QUESTION_CLASS + ' ' + TOC_CLASS },
-          h.a({ href: '#basicsQ4' }, basicsQuestions[3])
-        )
-      ),
-      h.h2({ className: SUBHEADER_CLASS }, subheadings[1]),
-      h.ul({ className: FAQ_LIST_CLASS },
-        h.li({ className: QUESTION_CLASS + ' ' + TOC_CLASS },
-          h.a({ href: '#featuresQ1' }, featuresQuestions[0])
-        ),
-        h.li({ className: QUESTION_CLASS + ' ' + TOC_CLASS },
-          h.a({ href: '#featuresQ2' }, featuresQuestions[1])
-        )
-      ),
-      h.h2({ className: SUBHEADER_CLASS }, subheadings[2]),
-      h.ul({ className: FAQ_LIST_CLASS },
-        h.li({ className: QUESTION_CLASS + ' ' + TOC_CLASS },
-          h.a({ href: '#developerQ1' }, developerQuestions[0])
-        ),
-        h.li({ className: QUESTION_CLASS + ' ' + TOC_CLASS },
-          h.a({ href: '#developerQ2' }, developerQuestions[1])
-        ),
-        h.li({ className: QUESTION_CLASS + ' ' + TOC_CLASS },
-          h.a({ href: '#developerQ3' }, developerQuestions[2])
-        )
-      )
-    );
-
-    // Create a section element that all other FAQ Content will go under.
-    let questionAnswerList =
-    h.section({ className: CONTENT_CLASS },
-      h.h2({ className: SUBHEADER_CLASS }, subheadings[0]),
-      // Create list of questions/answers under the Basics section.
-      h.ul({ className: FAQ_LIST_CLASS },
-        h.li({ className: QUESTION_CLASS, id: 'basicsQ1' }, basicsQuestions[0]),
-        h.li({ className: ANSWER_CLASS },
-          `JupyterLab allows users to arrange multiple Jupyter notebooks,
-          text editors, terminals, output areas, etc. on a single page with
-          multiple panels and tabs into one application. The codebase and UI of
-          JupyterLab is based on a flexible plugin system that makes it easy to
-          extend with new components.`
-        ),
-        h.li({ className: QUESTION_CLASS, id: 'basicsQ2' }, basicsQuestions[1]),
-        h.li({ className: ANSWER_CLASS },
-          `Central to the project is the Jupyter Notebook, a web-based
-          platform that allows users to combine live code, equations, narrative
-          text, visualizations, interactive dashboards and other media. Together
-          these building blocks make science and data reproducible across over
-          40 programming languages and combine to form what we call a
-          computational narrative.`
-        ),
-        h.li({ className: QUESTION_CLASS, id: 'basicsQ3' }, basicsQuestions[2]),
-        h.li({ className: ANSWER_CLASS },
-          `JupyterLab is currently in an alpha release and not ready for public
-          use as new features and bug fixes are being added very frequently. We
-          strongly recommend to back up your work before using JupyterLab.
-          However, testing, development, and user feedback are greatly
-          appreciated.`
-        ),
-        h.li({ className: QUESTION_CLASS, id: 'basicsQ4' }, basicsQuestions[3]),
-        h.li({ className: ANSWER_CLASS },
-          'Check out the JupyterLab tour ',
-          h.a({
-            className: ANCHOR_CLASS,
-            dataset: linker.populateVNodeDataset('about-jupyterlab:open')
-          }, 'here')
-        )
-      ),
-      h.h2({ className: SUBHEADER_CLASS }, subheadings[1]),
-      // Create list of questions/answers under the Features section.
-      h.ul({ className: FAQ_LIST_CLASS },
-        h.li({
-          className: QUESTION_CLASS,
-          id: 'featuresQ1'
-        }, featuresQuestions[0]),
-        h.li({ className: ANSWER_CLASS },
-          `To add more languages to the JupyterLab you must install a new
-          kernel. Installing a kernel is usually fairly simple and can be done
-          with a couple terminal commands. However the instructions for
-          installing kernels is different for each language. For further
-          instructions, click`,
-          h.a({
-            className: ANCHOR_CLASS,
-            href: 'https://jupyter.readthedocs.io/en/latest/install-kernel.html',
-            target: '_blank'
-          }, 'this'),
-          ' link.'
-        ),
-        h.li({
-          className: QUESTION_CLASS,
-          id: 'featuresQ2'
-        }, featuresQuestions[1]),
-        h.li({ className: ANSWER_CLASS },
-          `You can either publish your notebooks on GitHub or use a free service
-          such as `,
-          h.a({
-            className: ANCHOR_CLASS,
-            href: 'https://nbviewer.jupyter.org/',
-            target: '_blank'
-          }, 'nbviewer.org'),
-          ' to render your notebooks online.'
-        )
-      ),
-      h.h2({ className: SUBHEADER_CLASS }, subheadings[2]),
-      // Create list of questions/answers under the Developer section.
-      h.ul({ className: FAQ_LIST_CLASS },
-        h.li({
-          className: QUESTION_CLASS,
-          id: 'developerQ1'
-        }, developerQuestions[0]),
-        h.li({ className: ANSWER_CLASS },
-          'You can open an issue on our ',
-          h.a({
-            className: ANCHOR_CLASS,
-            href: 'https://github.com/jupyterlab/jupyterlab/issues',
-            target: '_blank'
-          }, 'GitHub repository'),
-          '. Please check already opened issues before posting.'
-        ),
-        h.li({
-          className: QUESTION_CLASS,
-          id: 'developerQ2'
-        }, developerQuestions[1]),
-        h.li({ className: ANSWER_CLASS },
-          `If you have any inquiries, concerns, or thought you found a security
-          vulnerability, please write to use at `,
-          h.a({
-            className: ANCHOR_CLASS,
-            href: 'mailto:security@jupyter.org'
-          }, 'security@jupyter.org'),
-          '. We will do our best to repond to you promptly.'
-        ),
-        h.li({
-          className: QUESTION_CLASS,
-          id: 'developerQ3'
-        }, developerQuestions[2]),
-        h.li({ className: ANSWER_CLASS },
-          `There are many ways to contribute to JupyterLab. Whether you are an
-          experienced Python programmer or a newcomer, any interested developers
-          are welcome. You can learn about the JupyterLab codebase by going
-          through our`,
-          h.a({
-            className: ANCHOR_CLASS,
-            href: 'https://jupyterlab-tutorial.readthedocs.io/en/latest/index.html',
-            target: '_blank'
-          }, 'tutorial walkthrough' ),
-          ' and ',
-          h.a({
-            className: ANCHOR_CLASS,
-            href: 'https://jupyterlab.github.io/jupyterlab/',
-            target: '_blank'
-          }, 'documentation'),
-          '. Also, feel free to ask questions on our ',
-          h.a({
-            className: ANCHOR_CLASS,
-            href: 'https://github.com/jupyterlab/jupyterlab',
-            target: '_blank'
-          }, 'github'),
-          ' or through any of our ',
-          h.a({
-            className: ANCHOR_CLASS,
-            href: 'http://jupyter.org/community.html',
-            target: '_blank'
-          }, 'community resources'),
-          '.'
-        )
-      )
-    );
-    return [faqHeader, questionList, questionAnswerList];
-  }
-
-  /**
-   * Handle `'activate-request'` messages.
-   */
-  protected onActivateRequest(msg: Message): void {
-    this.node.tabIndex = -1;
-    this.node.focus();
-  }
-
-  /**
-   * Handle `'close-request'` messages.
-   */
-  protected onCloseRequest(msg: Message): void {
-    super.onCloseRequest(msg);
-    this.dispose();
-  }
-
-  private _linker: CommandLinker;
-}
-
-
-/**
- * A namespace for `FaqWidget` statics.
- */
-export
-namespace FaqWidget {
-  /**
-   * Instantiation options for the FAQ widget.
-   */
-  export
-  interface IOptions {
-    /**
-     * A command linker instance.
-     */
-    linker: CommandLinker;
-  }
-}

+ 0 - 122
packages/faq-extension/style/index.css

@@ -10,125 +10,3 @@
   overflow-y: auto;
 }
 
-#faq-header {
-  width: 412px;
-  display: flex;
-  margin: 40px auto 40px auto;
-  text-align: center;
-}
-
-
-.jp-FAQ-content {
-  margin: 0 auto 70px auto;
-  display: block;
-  width: 94%;
-  max-width: 700px;
-}
-
-
-.jp-FAQ-h1 {
-  font-size: 26px;
-  font-weight: 400;
-  color: #313940;
-  margin: 10px 0 0 20px;
-}
-
-
-.jp-FAQ-h2 {
-  font-size: 14px;
-  font-weight: 400;
-  color: var(--md-grey-500);
-  margin: 28px 0 0 0;
-  margin-bottom: 8px;
-}
-
-
-.jp-FAQ-ul {
-  margin: 0 0 0 0;
-  padding: 0;
-}
-
-
-.jp-FAQ-question:target {
-  animation: highlight 0.9s cubic-bezier(0.15, 0.08, 0.54, 0.85);
-}
-
-
-@keyframes highlight {
-    0%   {background-color: transparent;}
-    50%  {background-color: var(--md-blue-100);}
-    100% {background-color: transparent;}
-}
-
-
-.jp-FAQ-question {
-  color: var(--jp-ui-font-color0);
-  list-style-type: none;
-  padding: 4px 16px;
-  margin-left: -16px;
-  display: inline-block;
-}
-
-
-.jp-FAQ-question > a {
-  font-size: 20px;
-  color: var(--jp-ui-font-color0);
-  font-weight: 400;
-  line-height: 150%;
-  list-style-type: none;
-  margin: 28px 0 0 0;
-  cursor: pointer;
-  text-decoration: none;
-}
-
-
-.jp-FAQ-question > a:hover {
-  color: var(--md-blue-500);
-}
-
-
-.jp-FAQ-answer{
-  font-size: 15px;
-  font-weight: 200;
-  color: var(--md-grey-500);
-  line-height: 160%;
-  border-left: 2px solid var(--md-grey-500);
-  padding-left: 25px;
-  list-style-type: none;
-  margin: 15px 0 15px 20px;
-}
-
-
-.jp-FAQ-toc {
-  display: block;
-}
-
-
-.jp-FAQ-toc:focus{
-  color: var(--md-blue-500);
-}
-
-
-li > jp-FAQ-answer {
-  color: var(--md-grey-500);
-  text-decoration: none;
-}
-
-
-.jp-FAQ-title {
-  color: var(--jp-ui-font-color0);
-  display: block;
-}
-
-
-.jp-FAQ-a {
-    text-decoration: none;
-    cursor: pointer;
-    color: var(--jp-brand-color1);
-}
-
-
-.jp-QuestionMarkIcon.jp-FAQ-QuestionMark {
-  height: 49px;
-  width: 49px;
-}