Skip to content

Latest commit

 

History

History
307 lines (259 loc) · 27 KB

File metadata and controls

307 lines (259 loc) · 27 KB

Архитектура проекта bitrix24-help-developer

Общее описание

Web Extension для Safari (macOS) и Google Chrome, которое помогает разработчикам Битрикс24 видеть ID полей сущностей при наведении курсора. Расширение работает на всех страницах с Битрикс24 и автоматически обнаруживает поля редактора сущностей.

Структура проекта

bitrix24-help-developer/
├── bitrix24-help-developer/              # Основное macOS приложение-обертка
│   ├── AppDelegate.swift                 # Точка входа приложения, управление жизненным циклом
│   ├── ViewController.swift              # Контроллер главного окна, взаимодействие с Safari Extension API
│   ├── Assets.xcassets/                  # Ресурсы приложения (иконки, цвета)
│   ├── Base.lproj/                       # Локализованные ресурсы
│   └── Resources/                        # HTML/CSS/JS ресурсы для окна приложения
│       ├── Main.html                     # HTML интерфейса окна приложения
│       ├── Script.js                     # JavaScript логика окна приложения
│       ├── Style.css                     # Стили окна приложения
│       └── Icon.png                      # Иконка приложения
│
├── bitrix24-help-developer Extension/    # Safari Web Extension
│   ├── SafariWebExtensionHandler.swift   # Обработчик нативных сообщений от расширения
│   ├── Info.plist                        # Конфигурация расширения для macOS
│   └── Resources/                        # Ресурсы расширения
│       ├── manifest.json                  # Манифест расширения (WebExtensions API)
│       ├── background.js                 # Background script для обработки событий расширения
│       ├── content.js                    # Content script - основная логика показа ID полей
│       ├── tooltip.css                   # Стили тултипа с ID полей
│       ├── popup.html                    # HTML интерфейса popup расширения
│       ├── popup.js                       # JavaScript логика popup
│       ├── popup.css                     # Стили popup
│       ├── images/                       # Иконки расширения различных размеров
│       └── _locales/                     # Локализация
│           └── en/
│               └── messages.json         # Тексты интерфейса на английском
│
├── bitrix24-help-developer Chrome Extension/  # Chrome Web Extension
│   └── Resources/                        # Ресурсы расширения
│       ├── manifest.json                  # Манифест расширения (Chrome MV3)
│       ├── background.js                 # Service worker для обработки событий расширения
│       ├── content.js                    # Content script - основная логика показа ID полей
│       ├── tooltip.css                   # Стили тултипа с ID полей
│       ├── popup.html                    # HTML интерфейса popup расширения
│       ├── popup.js                       # JavaScript логика popup
│       ├── popup.css                     # Стили popup
│       ├── images/                       # Иконки расширения различных размеров
│       └── _locales/                     # Локализация
│           └── en/
│               └── messages.json         # Тексты интерфейса на английском
│
└── bitrix24-help-developer.xcodeproj/    # Xcode проект
    └── project.pbxproj                   # Конфигурация проекта Xcode

Компоненты и их назначение

Основное приложение (bitrix24-help-developer/)

AppDelegate.swift

  • Назначение: Главный делегат приложения macOS
  • Функции:
    • applicationDidFinishLaunching: Инициализация при запуске
    • applicationShouldTerminateAfterLastWindowClosed: Автоматическое завершение при закрытии окна

ViewController.swift

  • Назначение: Управление главным окном приложения и взаимодействие с Safari Extension API
  • Функции:
    • viewDidLoad: Инициализация WebView и загрузка интерфейса
    • webView(_:didFinish:): Проверка состояния расширения после загрузки страницы
    • userContentController(_:didReceive:): Обработка сообщений от JavaScript для открытия настроек Safari

Resources/Main.html

  • Назначение: HTML интерфейс окна приложения
  • Содержимое: Отображение статуса расширения и кнопка для открытия настроек Safari

Resources/Script.js

  • Назначение: JavaScript логика окна приложения
  • Функции: Обновление UI в зависимости от состояния расширения

Safari Web Extension (bitrix24-help-developer Extension/)

SafariWebExtensionHandler.swift

  • Назначение: Обработчик нативных сообщений между расширением и macOS приложением
  • Функции:
    • beginRequest(with:): Обработка сообщений от browser.runtime.sendNativeMessage

Resources/manifest.json

  • Назначение: Конфигурация расширения по стандарту WebExtensions API
  • Ключевые настройки:
    • content_scripts: Инъекция content.js и tooltip.css на все страницы
    • permissions: Доступ к clipboard API для копирования ID и storage API для сохранения состояния
    • host_permissions: Доступ ко всем URL для работы на любых доменах Битрикс24
    • action: Конфигурация popup и иконки в панели инструментов Safari

Resources/content.js

  • Назначение: Основная логика расширения - обнаружение полей Битрикс24 и показ ID
  • Основные функции:
    • createTooltip(): Создание DOM элемента тултипа с кнопками копирования для списочных полей
    • extractFieldId(): Извлечение ID из data-cid, data-field-tag, атрибута name инпута в формате USER_FIELDS[ID] или data-id для канбан-колонок
    • extractFieldName(): Извлечение названия поля из элемента .ui-entity-editor-block-title-text для использования в имени класса Python dataclass
    • extractSelectFieldValues(): Извлечение всех значений из списочного поля (select) с их ID
    • isBitrix24Field(): Проверка, является ли элемент полем Битрикс24
    • isSelectField(): Проверка, является ли поле списочным (enumeration/select)
    • positionTooltip(): Позиционирование тултипа относительно элемента поля
    • showTooltip(): Отображение тултипа с ID поля (проверяет состояние расширения). Для списочных полей отображает ID и все значения с их ID, а также кнопки копирования в JSON и Python dataclass форматах
    • hideTooltip(): Скрытие тултипа
    • hideTooltipIfVisible(): Принудительное скрытие тултипа при выключении расширения
    • handleTooltipClick(): Копирование ID в буфер обмена при клике
    • copyToClipboard(): Универсальная функция копирования текста в буфер обмена
    • transliterate(): Транслитерация русского текста в латиницу для использования в ключах JSON и именах классов Python
    • generateJSONFormat(): Генерация JSON формата для списочных полей в виде {"translit_value": "ID" // value}
    • generatePythonDataclassFormat(): Генерация Python dataclass формата для списочных полей с классом на транслите и параметрами на транслите
    • showCopySuccess(): Показ визуального подтверждения успешного копирования с возможностью кастомного сообщения
    • attachHandlersToFields(): Привязка обработчиков событий к полям
    • loadExtensionState(): Загрузка состояния расширения из storage
    • init(): Инициализация расширения и настройка MutationObserver
    • Обработчик сообщений extensionStateChanged для обновления состояния в реальном времени

Алгоритм работы:

  1. При загрузке страницы проверяется наличие элементов Битрикс24
  2. К найденным полям добавляются обработчики mouseenter/mouseleave
  3. MutationObserver отслеживает динамически добавляемые поля
  4. При наведении извлекается ID и показывается тултип
  5. Для списочных полей дополнительно извлекаются все значения с их ID и отображаются в тултипе
  6. При клике на тултип ID копируется в буфер обмена

Resources/tooltip.css

  • Назначение: Стилизация тултипа с ID полей
  • Ключевые стили:
    • .bitrix24-field-id-tooltip: Основной контейнер тултипа (поддерживает многострочный текст для списочных полей)
    • .visible: Класс для показа тултипа с анимацией
    • .copied: Состояние после успешного копирования
    • .tooltip-id: Стили для отображения ID (моноширинный шрифт, поддерживает многострочный текст)
    • .tooltip-icon: Иконка копирования
    • .tooltip-buttons: Контейнер для кнопок копирования в JSON и Python форматах (отображается только для списочных полей)
    • .copy-btn: Стили кнопок копирования (JSON и Python)

Resources/background.js

  • Назначение: Background script для обработки событий расширения
  • Текущая функциональность: Базовая обработка сообщений между компонентами

Resources/popup.html, popup.js, popup.css

  • Назначение: Интерфейс popup расширения (открывается при клике на иконку в панели инструментов)
  • Основные функции:
    • loadExtensionState(): Загрузка состояния расширения из storage
    • saveExtensionState(): Сохранение состояния расширения и отправка сообщений во все вкладки
    • updateUI(): Обновление интерфейса в зависимости от состояния расширения
    • Переключатель включения/выключения расширения
    • Отображение текущего статуса (Включено/Выключено)

Resources/_locales/en/messages.json

  • Назначение: Локализация текстов интерфейса расширения
  • Содержимое: Название и описание расширения

Chrome Web Extension (bitrix24-help-developer Chrome Extension/)

Resources/manifest.json

  • Назначение: Конфигурация расширения для Chrome (Manifest V3)
  • Ключевые настройки:
    • manifest_version: 3 (Chrome MV3)
    • background.service_worker: Использует service worker вместо background scripts
    • content_scripts: Инъекция content.js и tooltip.css на все страницы
    • permissions: Доступ к clipboard API для копирования ID и storage API для сохранения состояния
    • host_permissions: Доступ ко всем URL для работы на любых доменах Битрикс24
    • action: Конфигурация popup и иконки в панели инструментов Chrome

Resources/background.js

  • Назначение: Service worker для обработки событий расширения в Chrome MV3
  • Особенности: Использует chrome.runtime API с fallback на browser.runtime для совместимости
  • Текущая функциональность: Базовая обработка сообщений между компонентами

Resources/content.js

  • Назначение: Основная логика расширения - обнаружение полей Битрикс24 и показ ID
  • Функциональность: Идентична Safari версии, использует chrome.storage API с fallback на browser.storage

Resources/popup.html, popup.js, popup.css

  • Назначение: Интерфейс popup расширения (открывается при клике на иконку в панели инструментов Chrome)
  • Основные функции: Идентичны Safari версии, адаптированы для использования chrome API вместо browser API

Resources/tooltip.css

  • Назначение: Стилизация тултипа с ID полей
  • Функциональность: Идентична Safari версии

Resources/_locales/en/messages.json

  • Назначение: Локализация текстов интерфейса расширения
  • Содержимое: Название и описание расширения

Архитектура взаимодействия компонентов

flowchart TD
    Safari[Safari Browser] --> ContentScript[content.js]
    ContentScript --> DOM[DOM страницы Битрикс24]
    DOM --> Fields[Поля сущностей]
    Fields -->|mouseenter| ContentScript
    ContentScript -->|проверка состояния| ExtensionState{Расширение<br/>включено?}
    ExtensionState -->|да| Tooltip[Тултип с ID]
    ExtensionState -->|нет| NoAction[Ничего не делать]
    Tooltip -->|click| Clipboard[Clipboard API]
    ContentScript -->|MutationObserver| DOM
    
    App[macOS App] --> ExtensionHandler[SafariWebExtensionHandler]
    ExtensionHandler <--> Background[background.js]
    Background <--> ContentScript
    
    Popup[popup.html] -->|переключение| Storage[browser.storage.local]
    Storage -->|состояние| Popup
    Popup -->|сообщение| ContentScript
    Storage -->|загрузка состояния| ContentScript
Loading

Поток данных

  1. Инициализация:

    • Safari загружает расширение
    • content.js инжектится на страницу
    • Загружается состояние расширения из storage (по умолчанию включено)
    • Проверяется наличие элементов Битрикс24
    • Настраивается MutationObserver
    • Настраивается обработчик сообщений для обновления состояния
  2. Управление состоянием:

    • Пользователь может включить/выключить расширение через popup
    • Состояние сохраняется в browser.storage.local с ключом bitrix24FieldIdEnabled
    • При изменении состояния отправляются сообщения во все вкладки
    • Content script обновляет состояние и скрывает тултип при выключении
  3. Обнаружение полей:

    • Поиск элементов с классом .ui-entity-editor-content-block
    • Проверка наличия атрибутов data-cid или data-field-tag
    • Привязка обработчиков событий (только если расширение включено)
  4. Показ ID:

    • При наведении курсора проверяется состояние расширения
    • Если расширение выключено, тултип не показывается
    • Если включено, извлекается ID из атрибутов
    • Для списочных полей (enumeration/select) дополнительно извлекаются все значения из <select> с их ID
    • Создается/обновляется тултип с ID поля (для списочных полей - ID и все значения в формате "ID: значение")
    • Тултип позиционируется относительно элемента поля (не курсора)
    • Позиция тултипа фиксирована относительно элемента, что позволяет навести на него курсор
  5. Копирование:

    • При клике на тултип ID копируется через Clipboard API
    • Для списочных полей доступны дополнительные кнопки копирования:
      • JSON формат: Генерирует JSON объект с ключами на транслите значений и ID в качестве значений, с комментариями оригинальных значений
      • Python dataclass формат: Генерирует Python dataclass класс с именем на транслите названия поля (извлекается из .ui-entity-editor-block-title-text), параметрами на транслите значений и ID в качестве значений по умолчанию. Если название поля не найдено, используется транслитерированный ID поля
    • Показывается визуальное подтверждение с возможностью кастомного сообщения
    • Fallback метод для старых браузеров через document.execCommand

Технические детали

Селекторы для обнаружения полей

  • Основной селектор: .ui-entity-editor-content-block[data-cid]
  • Альтернативный: элементы с data-field-tag внутри .ui-entity-editor-content-block
  • Поля с инпутами USER_FIELDS[ID]: элементы с классом .tasks-uf-panel-row, .js-id-item-set-item или содержащие инпут с атрибутом name в формате USER_FIELDS[ID]
  • Канбан-колонки: элементы с классом .main-kanban-column-body и атрибутом data-id
  • Списочные поля:
    • .ui-entity-editor-content-block-field-custom-select или .ui-entity-editor-content-block-field-enumeration с вложенным <select>
    • Элементы с data-items: .main-ui-control.main-ui-select или любой элемент с атрибутом data-items, содержащим JSON массив значений
    • Popup-списки: .popup-select-content или .main-ui-select-inner с элементами .main-ui-select-inner-item[data-item]
    • UI Selector Dialog: .ui-selector-dialog с элементами .ui-selector-item-title внутри .ui-selector-item-box

Приоритет извлечения ID

  1. data-cid - основной атрибут (приоритет)
  2. data-field-tag - запасной вариант
  3. Атрибут name инпута в формате USER_FIELDS[ID] - для полей в структуре tasks-uf-panel-row и подобных (извлекается ID из скобок)
  4. data-id - для канбан-колонок (элементы с классом .main-kanban-column-body)

Позиционирование тултипа

  • Фиксированное позиционирование относительно элемента поля (не курсора)
  • Позиционирование всегда слева от элемента поля
  • Смещение на 12px от границы элемента
  • Если не помещается слева полностью, тултип остается слева, но сдвигается так, чтобы быть максимально видимым
  • Автоматическая корректировка по вертикали: если не помещается снизу - сверху
  • Минимальные отступы 10px от краев viewport
  • Тултип не следует за курсором, что позволяет навести на него курсор для клика

Обработка списочных полей (enumeration/select)

  • Автоматическое определение списочных полей по классам ui-entity-editor-content-block-field-custom-select или наличию <select> элемента
  • Поддержка четырех форматов списочных полей:
    • Обычный select: значения извлекаются из <option> элементов с атрибутом value
    • Элемент с data-items: значения извлекаются из атрибута data-items элемента (обычно .main-ui-control.main-ui-select), содержащего JSON массив объектов с полями NAME, VALUE и IS_SELECTED
    • Popup-список с data-item: значения извлекаются из элементов .main-ui-select-inner-item с атрибутом data-item, содержащим JSON с полями NAME и VALUE
    • UI Selector Dialog: значения извлекаются из элементов .ui-selector-item-title внутри .ui-selector-dialog. ID ищется в data-атрибутах элементов (data-id, data-value), при отсутствии используется индекс элемента
  • Извлечение всех значений с их ID через функцию extractSelectFieldValues() (приоритет: ui-selector-dialog, затем элементы с data-items, затем popup-списки с data-item, затем обычные select)
  • Отображение в тултипе: первая строка - ID поля, последующие строки - все значения в формате "ID: значение"
  • Поддержка многострочного отображения через CSS свойство white-space: pre-line
  • Для списочных полей отображаются кнопки копирования в JSON и Python dataclass форматах:
    • JSON формат: {"translit_value": "ID" // value} - ключи на транслите значений, значения - ID, комментарии - оригинальные тексты
    • Python dataclass формат: Класс с именем на транслите названия поля (извлекается из .ui-entity-editor-block-title-text), параметрами на транслите значений, значениями по умолчанию - ID, комментарии - оригинальные тексты. Если название поля не найдено, используется транслитерированный ID поля
  • Транслитерация русского текста в латиницу выполняется функцией transliterate() для использования в ключах JSON и именах классов/параметров Python
  • Название поля извлекается функцией extractFieldName() из элемента .ui-entity-editor-block-title-text внутри блока поля

Обработка динамического контента

  • MutationObserver отслеживает добавление новых элементов в DOM
  • При обнаружении новых полей автоматически добавляются обработчики
  • Проверка выполняется с задержкой для оптимизации производительности

формат

  • JSON формат: {"translit_value": "ID" // value} - ключи на транслите значений, значения - ID, комментарии - оригинальные тексты
  • Python dataclass формат: Класс с именем на транслите названия поля (извлекается из .ui-entity-editor-block-title-text), параметрами на транслите значений, значениями по умолчанию - ID, комментарии - оригинальные тексты. Если название поля не найдено, используется транслитерированный ID поля