Руководство. Сборка надстройки Outlook для создания сообщенияTutorial: Build a message compose Outlook add-in

В этом руководстве разъясняется, как выполнить сборку надстройки Outlook, которую можно использовать в режиме создания сообщения для вставки содержимого в его текст.This tutorial teaches you how to build an Outlook add-in that can be used in message compose mode to insert content into the body of a message.

В этом руководстве описан порядок выполнения перечисленных ниже задач.In this tutorial, you will:

  • Создание проекта надстройки OutlookCreate an Outlook add-in project
  • Определение кнопок, отображаемых в окне создания сообщенияDefine buttons that will render in the compose message window
  • Реализация интерфейса первого запуска, который собирает сведения от пользователя и получает данные из внешней службыImplement a first-run experience that collects information from the user and fetches data from an external service
  • Реализация кнопки без пользовательского интерфейса, вызывающей функциюImplement a UI-less button that invokes a function
  • Реализация области задач, вставляющей содержимое в текст сообщенияImplement a task pane that inserts content into the body of a message

Необходимые условияPrerequisites

  • Node.js (версия 8.0.0 или более поздняя)Node.js (version 8.0.0 or later)

  • Последняя версия Yeoman и генератора Yeoman для надстроек Office. Выполните в командной строке указанную ниже команду, чтобы установить эти инструменты глобально.The latest version of Yeoman and the Yeoman generator for Office Add-ins. To install these tools globally, run the following command via the command prompt:

    npm install -g yo generator-office
    

    Примечание

    Даже если вы уже установили генератор Yeoman, рекомендуем обновить пакет до последней версии из npm.Even if you've previously installed the Yeoman generator, we recommend you update your package to the latest version from npm.

  • Outlook 2016 или более поздней версии для Windows (подключенный к учетной записи Office 365) или Outlook в ИнтернетеOutlook 2016 or later for Windows (connected to an Office 365 account) or Outlook on the web

  • Учетная запись GitHubA GitHub account

НастройкаSetup

Надстройка, создаваемая с помощью этого руководства, считывает элементы gist из учетной записи GitHub пользователя и добавляет выбранные элементы gist в текст сообщения.The add-in that you'll create in this tutorial will read gists from the user's GitHub account and add the selected gist to the body of a message. Выполните указанные ниже действия для создания двух новых элементов gist, с помощью которых можно проверить создаваемую надстройку.Complete the following steps to create two new gists that you can use to test the add-in you're going to build.

  1. Выполните вход в GitHub.Login to GitHub.

  2. Создайте новый элемент gist.Create a new gist.

    • В поле Gist description... (Описание gist) введите Hello World Markdown.In the Gist description... field, enter Hello World Markdown.

    • В поле **Filename including extension... ** (Имя файла с расширением) введите test.md.In the Filename including extension... field, enter test.md.

    • Добавьте в многострочное текстовое поле указанную ниже разметку.Add the following markdown to the multiline textbox:

      # Hello World
      
      This is content converted from Markdown!
      
      Here's a JSON sample:
      
        ```json
        {
          "foo": "bar"
        }
        ```
      
    • Нажмите кнопку Create public gist (Создать общедоступный элемент gist).Select the Create public gist button.

  3. Создайте другой элемент gist.Create another new gist.

    • В поле Gist description... (Описание gist) введите Hello World Html.In the Gist description... field, enter Hello World Html.

    • В поле **Filename including extension... ** (Имя файла с расширением) введите test.html.In the Filename including extension... field, enter test.html.

    • Добавьте в многострочное текстовое поле указанную ниже разметку.Add the following markdown to the multiline textbox:

      <html>
        <head>
          <style>
          h1 {
            font-family: Calibri;
          }
          </style>
        </head>
        <body>
          <h1>Hello World!</h1>
          <p>This is a test</p>
        </body>
      </html>
      
    • Нажмите кнопку Create public gist (Создать общедоступный элемент gist).Select the Create public gist button.

Создание проекта надстройки OutlookCreate an Outlook add-in project

Важно!

В настоящее время запрещено использовать пробелы в имени проекта надстройки или в пути к папке, в которой создается проект надстройки.Spaces are not currently permitted in the add-in project name or anywhere in the folder path where you create your add-in project. Если имя или путь к папке проекта надстройки содержит пробелы, локальный веб-сервер не запустится при выполнении команды npm start или npm run start:web.If your add-in's project name or folder path contains spaces, the local web server won't start when you run npm start or npm run start:web. Это ограничение установлено временно и будет снято после устранения исходной проблемы в генераторе Yeoman для надстроек Office.This limitation is temporary and will be eliminated when the underlying issue is resolved in the Yeoman generator for Office Add-ins.

С помощью генератора Yeoman создайте проект надстройки Outlook.Use the Yeoman generator to create an Outlook add-in project.

  1. Выполните приведенную ниже команду в командной строке и ответьте на вопросы, как показано ниже.Run the following command from the command prompt and then answer the prompts as follows:

    yo office
    
    • Выберите тип проекта - Office Add-in Task Pane projectChoose a project type - Office Add-in Task Pane project

    • Выберите тип сценария - JavascriptChoose a script type - Javascript

    • Как вы хотите назвать надстройку?What do you want to name your add-in? - git-the-gist

    • Какое клиентское приложение Office должно поддерживаться?Which Office client application would you like to support? - Outlook

    После завершения работы мастера генератор создаст проект и установит вспомогательные компоненты Node.After you complete the wizard, the generator will create the project and install supporting Node components.

  2. Перейдите к корневому каталогу проекта.Navigate to the root directory of the project.

    cd "git-the-gist"
    
  3. Эта надстройка будет использовать следующие библиотеки:This add-in will use the following libraries:

    • Библиотека Showdown для преобразования Markdown в HTMLShowdown library to convert Markdown to HTML
    • Библиотека URI.js для создания относительных URL-адресов.URI.js library to build relative URLs.
    • Библиотеки jquery для упрощения взаимодействий DOM.jquery library to simplify DOM interactions.

    Чтобы установить эти инструменты для своего проекта, выполните в корневом каталоге проекта указанную ниже команду.To install these tools for your project, run the following command in the root directory of the project:

    npm install showdown urijs jquery --save
    

Обновление манифестаUpdate the manifest

Манифест надстройки управляет ее отображением в Outlook.The manifest for an add-in controls how it appears in Outlook. Он определяет, как надстройка отображается в списке, а также задает кнопки на ленте и URL-адреса файлов HTML и JavaScript, используемых надстройкой.It defines the way the add-in appears in the add-in list and the buttons that appear on the ribbon, and it sets the URLs for the HTML and JavaScript files used by the add-in.

Указание страницы поддержкиSpecify a support page

Манифест, который создает генератор, содержит значение заполнителя для элемента SupportUrl, не являющееся действительным URL-адресом.The manifest that the generator creates contains a placeholder value for the SupportUrl element that's not a valid URL. Чтобы предотвратить сбой проверки файла, выполните указанные ниже действия.To prevent the file from failing validation, complete the following steps:

  1. В корневом каталоге проекта создайте новый файл с именем support.html и добавьте приведенную ниже разметку.In the root directory of the project, create a new file named support.html and add the following markup.

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, inline-scale=1">
        <title>Support</title>
      </head>
      <body>
        <h1>Support</h1>
        <p>This is the support page for the <b>Git the gist</b> add-in.</p>
        <p>In a real-world scenario, this page should provide support information for the add-in.</p>
      </body>
    </html>
    
  2. Откройте файл manifest.xml и измените элемент SupportUrl, чтобы он указывал на созданный файл support.html.Open the manifest.xml file and update the SupportUrl element to point to the support.html file that you created.

    <SupportUrl DefaultValue="https://localhost:3000/support.html" />
    

Указание основных сведенийSpecify basic information

Затем выполните приведенные ниже изменения в файле manifest.xml, чтобы указать некоторые основные сведения о надстройке.Next, make the following updates in the manifest.xml file to specify some basic information about the add-in:

  1. Найдите элемент ProviderName и замените значение по умолчанию на название вашей компании.Locate the ProviderName element and replace the default value with your company name.

    <ProviderName>Contoso</ProviderName>
    
  2. Найдите элемент Description, замените значение по умолчанию на описание надстройки и сохраните файл.Locate the Description element, replace the default value with a description of the add-in, and save the file.

    <Description DefaultValue="Allows users to access their GitHub gists."/>
    

Тестирование созданной надстройкиTest the generated add-in

Прежде чем продолжить, протестируйте базовую надстройку, созданную генератором, чтобы подтвердить правильную настройку проекта.Before going any further, let's test the basic add-in that the generator created to confirm that the project is set up correctly.

Примечание

Надстройки Office должны использовать HTTPS, а не HTTP, даже в случае разработки.Office Add-ins should use HTTPS, not HTTP, even when you are developing. Если вам будет предложено установить сертификат после того, как вы запустите одну из указанных ниже команд, примите предложение установить сертификат, предоставленный генератором Yeoman.If you are prompted to install a certificate after you run one of the following commands, accept the prompt to install the certificate that the Yeoman generator provides.

Совет

Если вы тестируете надстройку на компьютере Mac, перед продолжением выполните указанную ниже команду.If you're testing your add-in on Mac, run the following command before proceeding. После выполнения этой команды запустится локальный веб-сервер.When you run this command, the local web server will start.

npm run dev-server
  1. Выполните следующую команду в корневом каталоге своего проекта.Run the following command in the root directory of your project. После выполнения этой команды запустится локальный веб-сервер (если он еще не запущен).When you run this command, the local web server will start.

    npm start
    
  2. Выполните инструкции, приведенные в статье Загрузка неопубликованных надстроек Outlook для тестирования, чтобы загрузить неопубликованный файл manifest.xml, находящийся в корневом каталоге проекта.Follow the instructions in Sideload Outlook add-ins for testing to sideload the manifest.xml file that's located in the root directory of the project.

  3. Откройте в Outlook существующее сообщение и нажмите кнопку Показать область задач.In Outlook, open an existing message and select the Show Taskpane button. Если настройка выполнена правильно, откроется область задач и отобразится страница приветствия надстройки.If everything's been set up correctly, the task pane will open and render the add-in's welcome page.

    Снимок экрана с кнопкой и областью задач, добавленной примером

Определение кнопокDefine buttons

После проверки работы базовой надстройки можно ее настроить для добавления функций.Now that you've verified the base add-in works, you can customize it to add more functionality. По умолчанию манифест определяет только кнопки для окна чтения сообщения.By default, the manifest only defines buttons for the read message window. Можно обновить манифест, чтобы удалить кнопки из окна чтения сообщения и определить две новые кнопки для окна создания сообщения:Let's update the manifest to remove the buttons from the read message window and define two new buttons for the compose message window:

  • Insert gist (Вставить gist): кнопка, открывающая область задачInsert gist: a button that opens a task pane

  • Insert default gist (Вставить gist по умолчанию): кнопка, вызывающая функциюInsert default gist: a button that invokes a function

Удаление точки расширения MessageReadCommandSurfaceRemove the MessageReadCommandSurface extension point

Откройте файл manifest.xml и найдите элемент ExtensionPoint с типом MessageReadCommandSurface.Open the manifest.xml file and locate the ExtensionPoint element with type MessageReadCommandSurface. Удалите этот элемент ExtensionPoint (включая его закрывающий тег), чтобы удалить кнопки из окна чтения сообщения.Delete this ExtensionPoint element (including its closing tag) to remove the buttons from the read message window.

Добавление точки расширения MessageComposeCommandSurfaceAdd the MessageComposeCommandSurface extension point

Найдите в манифесте строку </DesktopFormFactor>.Locate the line in the manifest that reads </DesktopFormFactor>. Непосредственно перед ней вставьте приведенную ниже разметку XML.Immediately before this line, insert the following XML markup. Обратите внимание на указанные ниже особенности этой разметки.Note the following about this markup:

  • ExtensionPoint с xsi:type="MessageComposeCommandSurface" означает, что вы определяете кнопки для добавления окна составления сообщений.The ExtensionPoint with xsi:type="MessageComposeCommandSurface" indicates that you're defining buttons to add to the compose message window.

  • С помощью элемента OfficeTab с параметром id="TabDefault" вы указываете, что нужно добавить кнопки на вкладку ленты по умолчанию.By using an OfficeTab element with id="TabDefault", you're indicating you want to add the buttons to the default tab on the ribbon.

  • Элемент Group определяет группу новых кнопок, а ресурс groupLabel задает подпись группы.The Group element defines the grouping for the new buttons, with a label set by the groupLabel resource.

  • Первый элемент Control содержит элемент Action с параметром xsi:type="ShowTaskPane", поэтому эта кнопка открывает область задач.The first Control element contains an Action element with xsi:type="ShowTaskPane", so this button opens a task pane.

  • Второй элемент Control содержит элемент Action с параметром xsi:type="ExecuteFunction", поэтому кнопка вызывает функцию JavaScript, содержащуюся в файле функций.The second Control element contains an Action element with xsi:type="ExecuteFunction", so this button invokes a JavaScript function contained in the function file.

<!-- Message Compose -->
<ExtensionPoint xsi:type="MessageComposeCommandSurface">
  <OfficeTab id="TabDefault">
    <Group id="msgComposeCmdGroup">
      <Label resid="GroupLabel"/>
      <Control xsi:type="Button" id="msgComposeInsertGist">
        <Label resid="TaskpaneButton.Label"/>
        <Supertip>
          <Title resid="TaskpaneButton.Title"/>
          <Description resid="TaskpaneButton.Tooltip"/>
        </Supertip>
        <Icon>
          <bt:Image size="16" resid="Icon.16x16"/>
          <bt:Image size="32" resid="Icon.32x32"/>
          <bt:Image size="80" resid="Icon.80x80"/>
        </Icon>
        <Action xsi:type="ShowTaskpane">
          <SourceLocation resid="Taskpane.Url"/>
        </Action>
      </Control>
      <Control xsi:type="Button" id="msgComposeInsertDefaultGist">
        <Label resid="FunctionButton.Label"/>
        <Supertip>
          <Title resid="FunctionButton.Title"/>
          <Description resid="FunctionButton.Tooltip"/>
        </Supertip>
        <Icon>
          <bt:Image size="16" resid="Icon.16x16"/>
          <bt:Image size="32" resid="Icon.32x32"/>
          <bt:Image size="80" resid="Icon.80x80"/>
        </Icon>
        <Action xsi:type="ExecuteFunction">
          <FunctionName>insertDefaultGist</FunctionName>
        </Action>
      </Control>
    </Group>
  </OfficeTab>
</ExtensionPoint>

Обновление ресурсов в манифестеUpdate resources in the manifest

Приведенный выше код ссылается на подписи, подсказки и URL-адреса, которые необходимо определить, чтобы манифест был действительным.The previous code references labels, tooltips, and URLs that you need to define before the manifest will be valid. Вам нужно указать эту информацию в разделе Resources манифеста.You'll specify this information in the Resources section of the manifest.

  1. Найдите элемент Resources в файле манифеста и удалите весь элемент (включая его закрывающий тег).Locate the Resources element in the manifest file and delete the entire element (including its closing tag).

  2. Добавьте в том же местоположении следующую разметку, чтобы заменить только что удаленный элемент Resources:In that same location, add the following markup to replace the Resources element you just removed:

    <Resources>
      <bt:Images>
        <bt:Image id="Icon.16x16" DefaultValue="https://localhost:3000/assets/icon-16.png"/>
        <bt:Image id="Icon.32x32" DefaultValue="https://localhost:3000/assets/icon-32.png"/>
        <bt:Image id="Icon.80x80" DefaultValue="https://localhost:3000/assets/icon-80.png"/>
      </bt:Images>
      <bt:Urls>
        <bt:Url id="Commands.Url" DefaultValue="https://localhost:3000/commands.html"/>
        <bt:Url id="Taskpane.Url" DefaultValue="https://localhost:3000/taskpane.html"/>
      </bt:Urls>
      <bt:ShortStrings>
        <bt:String id="GroupLabel" DefaultValue="Git the gist"/>
        <bt:String id="TaskpaneButton.Label" DefaultValue="Insert gist"/>
        <bt:String id="TaskpaneButton.Title" DefaultValue="Insert gist"/>
        <bt:String id="FunctionButton.Label" DefaultValue="Insert default gist"/>
        <bt:String id="FunctionButton.Title" DefaultValue="Insert default gist"/>
      </bt:ShortStrings>
      <bt:LongStrings>
        <bt:String id="TaskpaneButton.Tooltip" DefaultValue="Displays a list of your gists and allows you to insert their contents into the current message."/>
        <bt:String id="FunctionButton.Tooltip" DefaultValue="Inserts the content of the gist you mark as default into the current message."/>
      </bt:LongStrings>
    </Resources>
    
  3. Сохраните изменения манифеста.Save your changes to the manifest.

Переустановка надстройкиReinstall the add-in

Так как вы ранее установили надстройку из файла, необходимо переустановить ее, чтобы изменения манифеста вступили в силу.Since you previously installed the add-in from a file, you must reinstall it in order for the manifest changes to take effect.

  1. Следуйте инструкциям в статье Загрузка неопубликованных надстроек Outlook для тестирования, чтобы найти раздел Пользовательские надстройки в нижней части диалогового окна Мои надстройки.Follow the instructions in Sideload Outlook add-ins for testing to locate the Custom add-ins section at the bottom of the My add-ins dialog box.

  2. Нажмите кнопку ... рядом с пунктом Git the gist, а затем выберите Удалить.Select the ... button next to the Git the gist entry and then choose Remove.

  3. Закройте окно Мои надстройки.Close the My add-ins window.

  4. Пользовательская кнопка должна моментально исчезнуть с ленты.The custom button should disappear from the ribbon momentarily.

  5. Следуйте инструкциям в статье Загрузка неопубликованных надстроек Outlook для тестирования, чтобы переустановить надстройку с помощью обновленного файла manifest.xml.Follow the instructions in Sideload Outlook add-ins for testing to reinstall the add-in using the updated manifest.xml file.

После повторной установки надстройки можно убедиться, что она установлена успешно, проверив команды Insert gist и Insert default gist в окне составления сообщений.After you've reinstalled the add-in, you can verify that it installed successfully by checking for the commands Insert gist and Insert default gist in a compose message window. Обратите внимание, что при выборе этих двух элементов ничего не происходит, так как вы еще не закончили создание этой надстройки.Note that nothing will happen if you select either of these items, because you haven't yet finished building this add-in.

  • При запуске этой надстройки в Outlook 2016 или более поздней версии для Windows отобразятся две новые кнопки на ленте окна составления сообщений: Insert gist и Insert default gist.If you're running this add-in in Outlook 2016 or later for Windows, you should see two new buttons in the ribbon of the compose message window: Insert gist and Insert default gist.

    Снимок экрана: лента в Outlook для Windows с выделенными кнопками надстройки

  • При запуске этой надстройки в Outlook в Интернете отобразится новая кнопка внизу окна составления сообщений.If you're running this add-in in Outlook on the web, you should see a new button at the bottom of the compose message window. Нажмите эту кнопку, чтобы просмотреть варианты Insert gist (Вставить gist) и Insert default gist (Вставить gist по умолчанию).Select that button to see the options Insert gist and Insert default gist.

    Снимок экрана: форма создания сообщения в Outlook в Интернете с выделенной кнопкой надстройки и всплывающим меню

Реализация интерфейса первого запускаImplement a first-run experience

Эта надстройка должна иметь возможность считывать элементы gist из учетной записи GitHub пользователя и определять, какой из них пользователь выбрал в качестве используемого по умолчанию.This add-in needs to be able to read gists from the user's GitHub account and identify which one the user has chosen as the default gist. Для выполнения этих целей надстройка должна предложить пользователю указать его имя пользователя GitHub и выбрать элемент gist в качестве используемого по умолчанию из его коллекции существующих элементов gist.In order to achieve these goals, the add-in must prompt the user to provide their GitHub username and choose a default gist from their collection of existing gists. Выполните действия, описанные в этом разделе, чтобы реализовать интерфейс первого запуска, отображающий диалоговое окно для получения этих сведений от пользователя.Complete the steps in this section to implement a first-run experience that will display a dialog to collect this information from the user.

Получение данных от пользователяCollect data from the user

Начнем с создания пользовательского интерфейса для самого диалогового окна.Let's start by creating the UI for the dialog itself. Создайте в папке ./src новую подпапку с именем settings.Within the ./src folder, create a new subfolder named settings. Создайте в папке ./src/settings файл с именем dialog.html и добавьте следующую разметку, чтобы определить базовую форму с вводом текста для имени пользователя GitHub, а также пустой список элементов gist, который будет заполнен с помощью JavaScript.In the ./src/settings folder, create a file named dialog.html, and add the following markup to define a very basic form with a text input for a GitHub username and an empty list for gists that'll be populated via JavaScript.

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
  <title>Settings</title>

  <!-- Office JavaScript API -->
  <script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script>

  <!-- For more information on Office UI Fabric, visit https://developer.microsoft.com/fabric. -->
  <link rel="stylesheet" href="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-core/9.6.1/css/fabric.min.css"/>

  <!-- Template styles -->
  <link href="dialog.css" rel="stylesheet" type="text/css" />
</head>

<body class="ms-font-l">
  <main>
    <section class="ms-font-m ms-fontColor-neutralPrimary">
      <div class="not-configured-warning ms-MessageBar ms-MessageBar--warning">
        <div class="ms-MessageBar-content">
          <div class="ms-MessageBar-icon">
            <i class="ms-Icon ms-Icon--Info"></i>
          </div>
          <div class="ms-MessageBar-text">
            Oops! It looks like you haven't configured <strong>Git the gist</strong> yet.
            <br/>
            Please configure your GitHub username and select a default gist, then try that action again!
          </div>
        </div>
      </div>
      <div class="ms-font-xxl">Settings</div>
      <div class="ms-Grid">
        <div class="ms-Grid-row">
          <div class="ms-TextField">
            <label class="ms-Label">GitHub Username</label>
            <input class="ms-TextField-field" id="github-user" type="text" value="" placeholder="Please enter your GitHub username">
          </div>
        </div>
        <div class="error-display ms-Grid-row">
          <div class="ms-font-l ms-fontWeight-semibold">An error occurred:</div>
          <pre><code id="error-text"></code></pre>
        </div>
        <div class="gist-list-container ms-Grid-row">
          <div class="list-title ms-font-xl ms-fontWeight-regular">Choose Default Gist</div>
          <form>
            <div id="gist-list">
            </div>
          </form>
        </div>
      </div>
      <div class="ms-Dialog-actions">
        <div class="ms-Dialog-actionsRight">
          <button class="ms-Dialog-action ms-Button ms-Button--primary" id="settings-done" disabled>
            <span class="ms-Button-label">Done</span>
          </button>
        </div>
      </div>
    </section>
  </main>
  <script type="text/javascript" src="../../node_modules/core-js/client/core.js"></script>
  <script type="text/javascript" src="../../node_modules/jquery/dist/jquery.js"></script>
  <script type="text/javascript" src="../helpers/gist-api.js"></script>
  <script type="text/javascript" src="dialog.js"></script>
</body>

</html>

Затем создайте в папке ./src/settings файл с именем dialog.css и добавьте приведенный ниже код, чтобы указать стили, используемые файлом dialog.html.Next, create a file in the ./src/settings folder named dialog.css, and add the following code to specify the styles that are used by dialog.html.

section {
  margin: 10px 20px;
}

.not-configured-warning {
  display: none;
}

.error-display {
  display: none;
}

.gist-list-container {
  margin: 10px -8px;
  display: none;
}

.list-title {
  border-bottom: 1px solid #a6a6a6;
  padding-bottom: 5px;
}

ul {
  margin-top: 10px;
}

.ms-ListItem-secondaryText,
.ms-ListItem-tertiaryText {
  padding-left: 15px;
}

Теперь, после определения пользовательского интерфейса диалогового окна, можно написать код для выполнения в нем действий.Now that you've defined the dialog UI, you can write the code that makes it actually do something. Создайте в папке ./src/settings файл с именем dialog.js и добавьте приведенный ниже код.Create a file in the ./src/settings folder named dialog.js and add the following code. Обратите внимание, что в этом коде используется jQuery для регистрации событий, а также функция messageParent для возвращения выбранных пользователем параметров вызывающей стороне.Note that this code uses jQuery to register events and uses the messageParent function to send the user's choices back to the caller.

(function(){
  'use strict';

  // The Office initialize function must be run each time a new page is loaded.
  Office.initialize = function(reason){
    jQuery(document).ready(function(){
      if (window.location.search) {
        // Check if warning should be displayed.
        var warn = getParameterByName('warn');
        if (warn) {
          $('.not-configured-warning').show();
        } else {
          // See if the config values were passed.
          // If so, pre-populate the values.
          var user = getParameterByName('gitHubUserName');
          var gistId = getParameterByName('defaultGistId');

          $('#github-user').val(user);
          loadGists(user, function(success){
            if (success) {
              $('.ms-ListItem').removeClass('is-selected');
              $('input').filter(function() {
                return this.value === gistId;
              }).addClass('is-selected').attr('checked', 'checked');
              $('#settings-done').removeAttr('disabled');
            }
          });
        }
      }

      // When the GitHub username changes,
      // try to load gists.
      $('#github-user').on('change', function(){
        $('#gist-list').empty();
        var ghUser = $('#github-user').val();
        if (ghUser.length > 0) {
          loadGists(ghUser);
        }
      });

      // When the Done button is selected, send the
      // values back to the caller as a serialized
      // object.
      $('#settings-done').on('click', function() {
        var settings = {};

        settings.gitHubUserName = $('#github-user').val();

        var selectedGist = $('.ms-ListItem.is-selected');
        if (selectedGist) {
          settings.defaultGistId = selectedGist.val();

          sendMessage(JSON.stringify(settings));
        }
      });
    });
  };

  // Load gists for the user using the GitHub API
  // and build the list.
  function loadGists(user, callback) {
    getUserGists(user, function(gists, error){
      if (error) {
        $('.gist-list-container').hide();
        $('#error-text').text(JSON.stringify(error, null, 2));
        $('.error-display').show();
        if (callback) callback(false);
      } else {
        $('.error-display').hide();
        buildGistList($('#gist-list'), gists, onGistSelected);
        $('.gist-list-container').show();
        if (callback) callback(true);
      }
    });
  }

  function onGistSelected() {
    $('.ms-ListItem').removeClass('is-selected').removeAttr('checked');
    $(this).children('.ms-ListItem').addClass('is-selected').attr('checked', 'checked');
    $('.not-configured-warning').hide();
    $('#settings-done').removeAttr('disabled');
  }

  function sendMessage(message) {
    Office.context.ui.messageParent(message);
  }

  function getParameterByName(name, url) {
    if (!url) {
      url = window.location.href;
    }
    name = name.replace(/[\[\]]/g, "\\$&");
    var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
      results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
  }
})();

Обновление настроек конфигурации webpackUpdate webpack config settings

Наконец, откройте файл webpack.config.js в корневом каталоге проекта и выполните описанные ниже шаги.Finally, open the file webpack.config.js file in the root directory of the project and complete the following steps.

  1. Найдите объект entry в объекте config и добавьте новую запись для dialog.Locate the entry object within the config object and add a new entry for dialog.

    dialog: "./src/settings/dialog.js"
    

    После этого новый объект entry будет выглядеть следующим образом:After you've done this, the new entry object will look like this:

    entry: {
      polyfill: "@babel/polyfill",
      taskpane: "./src/taskpane/taskpane.js",
      commands: "./src/commands/commands.js",
      dialog: "./src/settings/dialog.js"
    },
    
  2. Найдите массив plugins в объекте config и добавьте эти два новых объекта в конец массива.Locate the plugins array within the config object and add these two new objects to the end of that array.

    new HtmlWebpackPlugin({
      filename: "dialog.html",
      template: "./src/settings/dialog.html",
      chunks: ["polyfill", "dialog"]
    }),
    new CopyWebpackPlugin([
      {
        to: "dialog.css",
        from: "./src/settings/dialog.css"
      }
    ])
    

    После этого новый массив plugins будет выглядеть следующим образом:After you've done this, the new plugins array will look like this:

    plugins: [
      new CleanWebpackPlugin(),
      new HtmlWebpackPlugin({
        filename: "taskpane.html",
        template: "./src/taskpane/taskpane.html",
        chunks: ['polyfill', 'taskpane']
      }),
      new CopyWebpackPlugin([
      {
        to: "taskpane.css",
        from: "./src/taskpane/taskpane.css"
      }
      ]),
      new HtmlWebpackPlugin({
        filename: "commands.html",
        template: "./src/commands/commands.html",
        chunks: ["polyfill", "commands"]
      }),
      new HtmlWebpackPlugin({
        filename: "dialog.html",
        template: "./src/settings/dialog.html",
        chunks: ['polyfill', 'dialog']
      }),
      new CopyWebpackPlugin([
      {
        to: "dialog.css",
        from: "./src/settings/dialog.css"
      }
      ])
    ],
    
  3. Если веб-сервер работает, закройте окно команды узла.If the web server is running, close the node command window.

  4. Выполните указанную ниже команду, чтобы повторно собрать проект.Run the following command to rebuild the project.

    npm run build
    
  5. Выполните указанную ниже команду, чтобы запустить веб-сервер.Run the following command to start the web server.

    npm start
    

Получение данных из GitHubFetch data from GitHub

Только что созданный файл Dialog.js определяет, что надстройка должна загружать элементы gist, если возникает событие change для поля имени пользователя GitHub.The dialog.js file you just created specifies that the add-in should load gists when the change event fires for the GitHub username field. Для получения элементов gist пользователя из GitHub используется API элементов gist GitHub.To retrieve the user's gists from GitHub, you'll use the GitHub Gists API.

Создайте в папке ./src новую подпапку с именем helpers.Within the ./src folder, create a new subfolder named helpers. Создайте в папке ./src/helpers файл с именем gist-api.js и добавьте следующий код, чтобы получить элементы gist пользователя из GitHub и составить список элементов gist.In the ./src/helpers folder, create a file named gist-api.js, and add the following code to retrieve the user's gists from GitHub and build the list of gists.

function getUserGists(user, callback) {
  var requestUrl = 'https://api.github.com/users/' + user + '/gists';

  $.ajax({
    url: requestUrl,
    dataType: 'json'
  }).done(function(gists){
    callback(gists);
  }).fail(function(error){
    callback(null, error);
  });
}

function buildGistList(parent, gists, clickFunc) {
  gists.forEach(function(gist) {

    var listItem = $('<div/>')
      .appendTo(parent);

    var radioItem = $('<input>')
      .addClass('ms-ListItem')
      .addClass('is-selectable')
      .attr('type', 'radio')
      .attr('name', 'gists')
      .attr('tabindex', 0)
      .val(gist.id)
      .appendTo(listItem);

    var desc = $('<span/>')
      .addClass('ms-ListItem-primaryText')
      .text(gist.description)
      .appendTo(listItem);

    var desc = $('<span/>')
      .addClass('ms-ListItem-secondaryText')
      .text(' - ' + buildFileList(gist.files))
      .appendTo(listItem);

    var updated = new Date(gist.updated_at);

    var desc = $('<span/>')
      .addClass('ms-ListItem-tertiaryText')
      .text(' - Last updated ' + updated.toLocaleString())
      .appendTo(listItem);

    listItem.on('click', clickFunc);
  });  
}

function buildFileList(files) {

  var fileList = '';

  for (var file in files) {
    if (files.hasOwnProperty(file)) {
      if (fileList.length > 0) {
        fileList = fileList + ', ';
      }

      fileList = fileList + files[file].filename + ' (' + files[file].language + ')';
    }
  }

  return fileList;
}

Примечание

Вы могли заметить, что отсутствует кнопка для вызова диалогового окна параметров.You may have noticed that there's no button to invoke the settings dialog. Вместо этого надстройка будет проверять наличие конфигурации при нажатии пользователем кнопки Insert gist (Вставить gist) или Insert default gist (Вставить gist по умолчанию).Instead, the add-in will check whether it has been configured when the user selects either the Insert default gist button or the Insert gist button. Если конфигурация надстройки еще не выполнена, диалоговое окно параметров предложит пользователю выполнить настройку, прежде чем продолжить.If the add-in has not yet been configured, the settings dialog will prompt the user to configure before proceeding.

Реализация кнопки без пользовательского интерфейсаImplement a UI-less button

Эта кнопка надстройки Insert default gist (Вставить gist по умолчанию) является кнопкой без пользовательского интерфейса, вызывающей функцию JavaScript вместо открытия области задач, выполняемого многими кнопками надстройки.This add-in's Insert default gist button is a UI-less button that will invoke a JavaScript function, rather than open a task pane like many add-in buttons do. Если пользователь нажимает кнопку Insert gist (Вставить gist), соответствующая функция JavaScript проверяет наличие конфигурации надстройки.When the user selects the Insert default gist button, the corresponding JavaScript function will check whether the add-in has been configured.

  • Если конфигурация надстройки уже выполнена, функция загружает содержимое элемента gist, выбранного пользователем в качестве используемого по умолчанию, и вставляет его в текст сообщения.If the add-in has already been configured, the function will load the content of the gist that the user has selected as the default and insert it into the body of the message.

  • Если конфигурация надстройки еще не выполнена, диалоговое окно параметров предложит пользователю предоставить нужные сведения.If the add-in hasn't yet been configured, then the settings dialog will prompt the user to provide the required information.

Обновление файла функции (HTML)Update the function file (HTML)

Функция, вызываемая кнопкой без пользовательского интерфейса, должна быть определена в файле, указанном в элементе FunctionFile манифеста для соответствующего форм-фактора.A function that's invoked by a UI-less button must be defined in the file that's specified by the FunctionFile element in the manifest for the corresponding form factor. Этот манифест надстройки указывает https://localhost:3000/commands.html в качестве файла функции.This add-in's manifest specifies https://localhost:3000/commands.html as the function file.

Откройте файл ./src/commands/commands.html и замените все содержимое приведенной ниже разметкой.Open the file ./src/commands/commands.html and replace the entire contents with the following markup.

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />

    <!-- Office JavaScript API -->
    <script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script>

    <script type="text/javascript" src="../node_modules/jquery/dist/jquery.js"></script>
    <script type="text/javascript" src="../node_modules/showdown/dist/showdown.min.js"></script>
    <script type="text/javascript" src="../node_modules/urijs/src/URI.min.js"></script>
    <script type="text/javascript" src="../src/helpers/addin-config.js"></script>
    <script type="text/javascript" src="../src/helpers/gist-api.js"></script>
</head>

<body>
  <!-- NOTE: The body is empty on purpose. Since functions in commands.js are
       invoked via a button, there is no UI to render. -->
</body>

</html>

Обновление файла функции (JavaScript)Update the function file (JavaScript)

Откройте файл ./src/commands/commands.js и замените все содержимое приведенным ниже кодом.Open the file ./src/commands/commands.js and replace the entire contents with the following code. Обратите внимание, если функция insertDefaultGist определяет, что конфигурация надстройки не выполнена, добавляется параметр ?warn=1 к URL-адресу диалогового окна.Note that if the insertDefaultGist function determines the add-in has not yet been configured, it adds the ?warn=1 parameter to the dialog URL. Благодаря этому в диалоговом окне параметров отображается панель сообщений, определенная в файле ./settings/dialog.html, которая сообщает пользователю причину появления диалогового окна.Doing so makes the settings dialog render the message bar that's defined in ./settings/dialog.html, to tell the user why they're seeing the dialog.

var config;
var btnEvent;

// The initialize function must be run each time a new page is loaded.
Office.initialize = function (reason) {
};

// Add any ui-less function here.
function showError(error) {
  Office.context.mailbox.item.notificationMessages.replaceAsync('github-error', {
    type: 'errorMessage',
    message: error
  }, function(result){
  });
}

var settingsDialog;

function insertDefaultGist(event) {

  config = getConfig();

  // Check if the add-in has been configured.
  if (config && config.defaultGistId) {
    // Get the default gist content and insert.
    try {
      getGist(config.defaultGistId, function(gist, error) {
        if (gist) {
          buildBodyContent(gist, function (content, error) {
            if (content) {
              Office.context.mailbox.item.body.setSelectedDataAsync(content,
                {coercionType: Office.CoercionType.Html}, function(result) {
                  event.completed();
              });
            } else {
              showError(error);
              event.completed();
            }
          });
        } else {
          showError(error);
          event.completed();
        }
      });
    } catch (err) {
      showError(err);
      event.completed();
    }

  } else {
    // Save the event object so we can finish up later.
    btnEvent = event;
    // Not configured yet, display settings dialog with
    // warn=1 to display warning.
    var url = new URI('../src/settings/dialog.html?warn=1').absoluteTo(window.location).toString();
    var dialogOptions = { width: 20, height: 40, displayInIframe: true };

    Office.context.ui.displayDialogAsync(url, dialogOptions, function(result) {
      settingsDialog = result.value;
      settingsDialog.addEventHandler(Microsoft.Office.WebExtension.EventType.DialogMessageReceived, receiveMessage);
      settingsDialog.addEventHandler(Microsoft.Office.WebExtension.EventType.DialogEventReceived, dialogClosed);
    });
  }
}

function receiveMessage(message) {
  config = JSON.parse(message.message);
  setConfig(config, function(result) {
    settingsDialog.close();
    settingsDialog = null;
    btnEvent.completed();
    btnEvent = null;
  });
}

function dialogClosed(message) {
  settingsDialog = null;
  btnEvent.completed();
  btnEvent = null;
}

function getGlobal() {
  return (typeof self !== "undefined") ? self :
    (typeof window !== "undefined") ? window :
    (typeof global !== "undefined") ? global :
    undefined;
}

var g = getGlobal();

// The add-in command functions need to be available in global scope.
g.insertDefaultGist = insertDefaultGist;

Создание файла для управления параметрами конфигурацииCreate a file to manage configuration settings

HTML-файл функции ссылается на файл под названием addin-config.js, которого еще не существует.The HTML function file references a file named addin-config.js, which doesn't yet exist. Создайте файл с именем addin-config.js в папке ./src/helpers и добавьте указанный ниже код.Create a file named addin-config.js in the ./src/helpers folder and add the following code. В этом коде используется объект RoamingSettings, позволяющий получать и задавать значения конфигурации.This code uses the RoamingSettings object to get and set configuration values.

function getConfig() {
  var config = {};

  config.gitHubUserName = Office.context.roamingSettings.get('gitHubUserName');
  config.defaultGistId = Office.context.roamingSettings.get('defaultGistId');

  return config;
}

function setConfig(config, callback) {
  Office.context.roamingSettings.set('gitHubUserName', config.gitHubUserName);
  Office.context.roamingSettings.set('defaultGistId', config.defaultGistId);

  Office.context.roamingSettings.saveAsync(callback);
}

Создание новых функций для обработки элементов gistCreate new functions to process gists

Затем откройте файл ./src/helpers/gist-api.js и добавьте указанные ниже функции.Next, open the ./src/helpers/gist-api.js file and add the following functions. Обратите внимание на следующее:Note the following:

  • Если элемент gist содержит код HTML, надстройка вставит HTML-код в текст сообщения без изменений.If the gist contains HTML, the add-in will insert the HTML as-is into the body of the message.

  • Если элемент gist содержит код Markdown, надстройка воспользуется библиотекой Showdown, чтобы преобразовать формат Markdown в HTML, и вставит получившийся HTML-код в текст сообщения.If the gist contains Markdown, the add-in will use the Showdown library to convert the Markdown to HTML, and will then insert the resulting HTML into the body of the message.

  • Если элемент gist содержит любой код, отличный от HTML или Markdown, надстройка вставит его в текст сообщения как фрагмент кода.If the gist contains anything other than HTML or Markdown, the add-in will insert it into the body of the message as a code snippet.

function getGist(gistId, callback) {
  var requestUrl = 'https://api.github.com/gists/' + gistId;

  $.ajax({
    url: requestUrl,
    dataType: 'json'
  }).done(function(gist){
    callback(gist);
  }).fail(function(error){
    callback(null, error);
  });
}

function buildBodyContent(gist, callback) {
  // Find the first non-truncated file in the gist
  // and use it.
  for (var filename in gist.files) {
    if (gist.files.hasOwnProperty(filename)) {
      var file = gist.files[filename];
      if (!file.truncated) {
        // We have a winner.
        switch (file.language) {
          case 'HTML':
            // Insert as-is.
            callback(file.content);
            break;
          case 'Markdown':
            // Convert Markdown to HTML.
            var converter = new showdown.Converter();
            var html = converter.makeHtml(file.content);
            callback(html);
            break;
          default:
            // Insert contents as a <code> block.
            var codeBlock = '<pre><code>';
            codeBlock = codeBlock + file.content;
            codeBlock = codeBlock + '</code></pre>';
            callback(codeBlock);
        }
        return;
      }
    }
  }
  callback(null, 'No suitable file found in the gist');
}

Тестирование кнопкиTest the button

Сохраните все изменения и выполните в командной строке команду npm start, если сервер еще не запущен.Save all of your changes and run npm start from the command prompt, if the server isn't already running. Затем выполните указанные ниже действия, чтобы протестировать кнопку Insert default gist (Вставить gist по умолчанию).Then complete the following steps to test the Insert default gist button.

  1. Откройте Outlook и создайте новое сообщение.Open Outlook and compose a new message.

  2. В окне создания сообщения нажмите кнопку Insert default gist (Вставить gist по умолчанию).In the compose message window, select the Insert default gist button. Должно появиться предложение по выполнению конфигурации надстройки.You should be prompted to configure the add-in.

    Снимок экрана с предложением конфигурации в надстройке

  3. В диалоговом окне параметров введите имя пользователя GitHub, а затем нажмите кнопку TAB или щелкните в другом месте диалогового окна, чтобы вызвать событие change, которое должно загрузить ваш список элементов gist.In the settings dialog, enter your GitHub username and then either Tab or click elsewhere in the dialog to invoke the change event, which should load your list of gists. Выберите элемент gist в качестве используемого по умолчанию и нажмите кнопку Done (Готово).Select a gist to be the default, and select Done.

    Снимок экрана с диалоговым окном параметров надстройки

  4. Снова нажмите кнопку Insert default gist (Вставить gist по умолчанию).Select the Insert default gist button again. На этот раз содержимое элемента gist должно быть вставлено в текст сообщения.This time, you should see the contents of the gist inserted into the body of the email.

    Примечание

    Outlook для Windows: чтобы применить последние параметры, может потребоваться закрытие и повторное открытие окна создания сообщения.Outlook for Windows: To pick up the latest settings, you may need to close and reopen the compose message window.

Реализация области задачImplement a task pane

Эта кнопка Insert gist (Вставить gist) надстройки открывает область задач и отображает элементы gist пользователя.This add-in's Insert gist button will open a task pane and display the user's gists. После этого пользователь сможет выбрать один из элементов gist для вставки в текст сообщения.The user can then select one of the gists to insert into the body of the message. Если пользователь еще не выполнил конфигурацию надстройки, ему будет предложено сделать это.If the user has not yet configured the add-in, they will be prompted to do so.

Указание HTML для области задачSpecify the HTML for the task pane

В созданном вами проекте HTML области задач указан в файле ./src/taskpane/taskpane.html.In the project that you've created, the task pane HTML is specified in the file ./src/taskpane/taskpane.html. Откройте этот файл и замените все содержимое приведенной ниже разметкой.Open that file and replace the entire contents with the following markup.

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Contoso Task Pane Add-in</title>

    <!-- Office JavaScript API -->
    <script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script>

    <!-- For more information on Office UI Fabric, visit https://developer.microsoft.com/fabric. -->
    <link rel="stylesheet" href="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-core/9.6.1/css/fabric.min.css"/>

    <!-- Template styles -->
    <link href="taskpane.css" rel="stylesheet" type="text/css" />
</head>

<body class="ms-font-l ms-landing-page">
  <main class="ms-landing-page__main">
    <section class="ms-landing-page__content ms-font-m ms-fontColor-neutralPrimary">
      <div id="not-configured" style="display: none;">
        <div class="centered ms-font-xxl ms-u-textAlignCenter">Welcome!</div>
        <div class="ms-font-xl" id="settings-prompt">Please choose the <strong>Settings</strong> icon at the bottom of this window to configure this add-in.</div>
      </div>
      <div id="gist-list-container" style="display: none;">
        <form>
          <div id="gist-list">
          </div>
        </form>
      </div>
      <div id="error-display" style="display: none;" class="ms-u-borderBase ms-fontColor-error ms-font-m ms-bgColor-error ms-borderColor-error">
      </div>
    </section>
    <button class="ms-Button ms-Button--primary" id="insert-button" tabindex=0 disabled>
      <span class="ms-Button-label">Insert</span>
    </button>
  </main>
  <footer class="ms-landing-page__footer ms-bgColor-themePrimary">
    <div class="ms-landing-page__footer--left">
      <img src="../../assets/logo-filled.png" />
      <h1 class="ms-font-xl ms-fontWeight-semilight ms-fontColor-white">Git the gist</h1>
    </div>
    <div id="settings-icon" class="ms-landing-page__footer--right" aria-label="Settings" tabindex=0>
      <i class="ms-Icon enlarge ms-Icon--Settings ms-fontColor-white"></i>
    </div>
  </footer>
  <script type="text/javascript" src="../node_modules/jquery/dist/jquery.js"></script>
  <script type="text/javascript" src="../node_modules/showdown/dist/showdown.min.js"></script>
  <script type="text/javascript" src="../node_modules/urijs/src/URI.min.js"></script>
  <script type="text/javascript" src="../src/helpers/addin-config.js"></script>
  <script type="text/javascript" src="../src/helpers/gist-api.js"></script>
  <script type="text/javascript" src="taskpane.js"></script>
</body>

</html>

Указание CSS для области задачSpecify the CSS for the task pane

В созданном вами проекте CSS области задач указан в файле ./src/taskpane/taskpane.css.In the project that you've created, the task pane CSS is specified in the file ./src/taskpane/taskpane.css. Откройте этот файл и замените все содержимое приведенным ниже кодом.Open that file and replace the entire contents with the following code.

/* Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See full license in root of repo. */
html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: auto; }

body {
  position: relative;
  font-size: 16px; }

main {
  height: 100%;
  overflow-y: auto; }

footer {
  width: 100%;
  position: relative;
  bottom: 0;
  margin-top: 10px;}

p, h1, h2, h3, h4, h5, h6 {
  margin: 0;
  padding: 0; }

ul {
  padding: 0; }

#settings-prompt {
  margin: 10px 0;
}

#error-display {
  padding: 10px;
}

#insert-button {
  margin: 0 10px;
}

.clearfix {
  display: block;
  clear: both;
  height: 0; }

.pointerCursor {
  cursor: pointer; }

.invisible {
  visibility: hidden; }

.undisplayed {
  display: none; }

.ms-Icon.enlarge {
  position: relative;
  font-size: 20px;
  top: 4px; }

.ms-ListItem-secondaryText,
.ms-ListItem-tertiaryText {
  padding-left: 15px;
}

.ms-landing-page {
  display: -webkit-flex;
  display: flex;
  -webkit-flex-direction: column;
          flex-direction: column;
  -webkit-flex-wrap: nowrap;
          flex-wrap: nowrap;
  height: 100%; }
  .ms-landing-page__main {
    display: -webkit-flex;
    display: flex;
    -webkit-flex-direction: column;
            flex-direction: column;
    -webkit-flex-wrap: nowrap;
            flex-wrap: nowrap;
    -webkit-flex: 1 1 0;
            flex: 1 1 0;
    height: 100%; }

  .ms-landing-page__content {
    display: -webkit-flex;
    display: flex;
    -webkit-flex-direction: column;
            flex-direction: column;
    -webkit-flex-wrap: nowrap;
            flex-wrap: nowrap;
    height: 100%;
    -webkit-flex: 1 1 0;
            flex: 1 1 0;
    padding: 20px; }
    .ms-landing-page__content h2 {
      margin-bottom: 20px; }
  .ms-landing-page__footer {
    display: -webkit-inline-flex;
    display: inline-flex;
    -webkit-justify-content: center;
            justify-content: center;
    -webkit-align-items: center;
            align-items: center; }
    .ms-landing-page__footer--left {
      transition: background ease 0.1s, color ease 0.1s;
      display: -webkit-inline-flex;
      display: inline-flex;
      -webkit-justify-content: flex-start;
              justify-content: flex-start;
      -webkit-align-items: center;
              align-items: center;
      -webkit-flex: 1 0 0px;
              flex: 1 0 0px;
      padding: 20px; }
      .ms-landing-page__footer--left:active, .ms-landing-page__footer--left:hover {
        background: #005ca4;
        cursor: pointer; }
      .ms-landing-page__footer--left:active {
        background: #005ca4; }
      .ms-landing-page__footer--left--disabled {
        opacity: 0.6;
        pointer-events: none;
        cursor: not-allowed; }
        .ms-landing-page__footer--left--disabled:active, .ms-landing-page__footer--left--disabled:hover {
          background: transparent; }
      .ms-landing-page__footer--left img {
        width: 40px;
        height: 40px; }
      .ms-landing-page__footer--left h1 {
        -webkit-flex: 1 0 0px;
                flex: 1 0 0px;
        margin-left: 15px;
        text-align: left;
        width: auto;
        max-width: auto;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis; }
    .ms-landing-page__footer--right {
      transition: background ease 0.1s, color ease 0.1s;
      padding: 29px 20px; }
      .ms-landing-page__footer--right:active, .ms-landing-page__footer--right:hover {
        background: #005ca4;
        cursor: pointer; }
      .ms-landing-page__footer--right:active {
        background: #005ca4; }
      .ms-landing-page__footer--right--disabled {
        opacity: 0.6;
        pointer-events: none;
        cursor: not-allowed; }
        .ms-landing-page__footer--right--disabled:active, .ms-landing-page__footer--right--disabled:hover {
          background: transparent; }

Указание JavaScript для области задачSpecify the JavaScript for the task pane

В созданном вами проекте область задач JavaScript указана в файле ./src/taskpane/taskpane.js.In the project that you've created, the task pane JavaScript is specified in the file ./src/taskpane/taskpane.js. Откройте этот файл и замените все содержимое приведенным ниже кодом.Open that file and replace the entire contents with the following code.

(function(){
  'use strict';

  var config;
  var settingsDialog;

  Office.initialize = function(reason){

    jQuery(document).ready(function(){

      config = getConfig();

      // Check if add-in is configured.
      if (config && config.gitHubUserName) {
        // If configured, load the gist list.
        loadGists(config.gitHubUserName);
      } else {
        // Not configured yet.
        $('#not-configured').show();
      }

      // When insert button is selected, build the content
      // and insert into the body.
      $('#insert-button').on('click', function(){
        var gistId = $('.ms-ListItem.is-selected').val();
        getGist(gistId, function(gist, error) {
          if (gist) {
            buildBodyContent(gist, function (content, error) {
              if (content) {
                Office.context.mailbox.item.body.setSelectedDataAsync(content,
                  {coercionType: Office.CoercionType.Html}, function(result) {
                    if (result.status === Office.AsyncResultStatus.Failed) {
                      showError('Could not insert gist: ' + result.error.message);
                    }
                });
              } else {
                showError('Could not create insertable content: ' + error);
              }
            });
          } else {
            showError('Could not retrieve gist: ' + error);
          }
        });
      });

      // When the settings icon is selected, open the settings dialog.
      $('#settings-icon').on('click', function(){
        // Display settings dialog.
        var url = new URI('../src/settings/dialog.html').absoluteTo(window.location).toString();
        if (config) {
          // If the add-in has already been configured, pass the existing values
          // to the dialog.
          url = url + '?gitHubUserName=' + config.gitHubUserName + '&defaultGistId=' + config.defaultGistId;
        }

        var dialogOptions = { width: 20, height: 40, displayInIframe: true };

        Office.context.ui.displayDialogAsync(url, dialogOptions, function(result) {
          settingsDialog = result.value;
          settingsDialog.addEventHandler(Microsoft.Office.WebExtension.EventType.DialogMessageReceived, receiveMessage);
          settingsDialog.addEventHandler(Microsoft.Office.WebExtension.EventType.DialogEventReceived, dialogClosed);
        });
      })
    });
  };

  function loadGists(user) {
    $('#error-display').hide();
    $('#not-configured').hide();
    $('#gist-list-container').show();

    getUserGists(user, function(gists, error) {
      if (error) {

      } else {
        $('#gist-list').empty();
        buildGistList($('#gist-list'), gists, onGistSelected);
      }
    });
  }

  function onGistSelected() {
    $('.ms-ListItem').removeClass('is-selected').removeAttr('checked');
    $(this).children('.ms-ListItem').addClass('is-selected').attr('checked', 'checked');
    $('#insert-button').removeAttr('disabled');
  }

  function showError(error) {
    $('#not-configured').hide();
    $('#gist-list-container').hide();
    $('#error-display').text(error);
    $('#error-display').show();
  }

  function receiveMessage(message) {
    config = JSON.parse(message.message);
    setConfig(config, function(result) {
      settingsDialog.close();
      settingsDialog = null;
      loadGists(config.gitHubUserName);
    });
  }

  function dialogClosed(message) {
    settingsDialog = null;
  }
})();

Тестирование кнопкиTest the button

Сохраните все изменения и выполните в командной строке команду npm start, если сервер еще не запущен.Save all of your changes and run npm start from the command prompt, if the server isn't already running. Затем выполните указанные ниже действия, чтобы протестировать кнопку Insert gist (Вставить gist).Then complete the following steps to test the Insert gist button.

  1. Откройте Outlook и создайте новое сообщение.Open Outlook and compose a new message.

  2. В окне создания сообщения нажмите кнопку Insert gist (Вставить gist).In the compose message window, select the Insert gist button. Справа от формы создания сообщения должна открыться область задач.You should see a task pane open to the right of the compose form.

  3. В области задач выберите элемент gist Hello World Html и нажмите кнопку Insert (Вставить) для вставки этого элемента gist в текст сообщения.In the task pane, select the Hello World Html gist and select Insert to insert that gist into the body of the message.

Снимок экрана с областью задач надстройки

Дальнейшие действияNext steps

С помощью этого руководства вы выполнили сборку надстройки Outlook, которую можно использовать в режиме создания сообщения для вставки содержимого в его текст.In this tutorial, you've created an Outlook add-in that can be used in message compose mode to insert content into the body of a message. Чтобы узнать больше о разработке надстроек Outlook, перейдите к следующей статье:To learn more about developing Outlook add-ins, continue to the following article: