From e9a5f850e79a5e37604c4470358882e6d617ca01 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Fri, 26 Jan 2024 15:17:57 +0100 Subject: [PATCH 1/6] refactor: Move things closer to where they're used --- spec/workers/copy_project_job_spec.rb | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/spec/workers/copy_project_job_spec.rb b/spec/workers/copy_project_job_spec.rb index 95e89d8bc4d4..763ede6554b7 100644 --- a/spec/workers/copy_project_job_spec.rb +++ b/spec/workers/copy_project_job_spec.rb @@ -29,9 +29,6 @@ require 'spec_helper' RSpec.describe CopyProjectJob, type: :model do - let(:project) { create(:project, public: false) } - let(:user) { create(:user) } - let(:role) { create(:project_role, permissions: [:copy_projects]) } let(:params) { { name: 'Copy', identifier: 'copy' } } let(:maildouble) { double('Mail::Message', deliver: true) } @@ -191,18 +188,22 @@ end end - shared_context 'copy project' do - before do - described_class.new.tap do |job| - job.perform user_id: user.id, - source_project_id: project_to_copy.id, - target_project_params: params, - associations_to_copy: [:members] + describe 'perform' do + let(:project) { create(:project, public: false) } + let(:user) { create(:user) } + let(:role) { create(:project_role, permissions: [:copy_projects]) } + + shared_context 'copy project' do + before do + described_class.new.tap do |job| + job.perform user_id: user.id, + source_project_id: project_to_copy.id, + target_project_params: params, + associations_to_copy: [:members] + end end end - end - describe 'perform' do before do login_as(user) expect(User).to receive(:current=).with(user).at_least(:once) From ac550bfd2a2b2d2eb87ae4f9344e9352e109bf3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Mon, 29 Jan 2024 09:41:04 +0100 Subject: [PATCH 2/6] Use non-deprecated call option for imap ssl https://community.openproject.org/work_packages/51799 --- lib/redmine/imap.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/redmine/imap.rb b/lib/redmine/imap.rb index c54ff68f0ff1..7870c18a1b16 100644 --- a/lib/redmine/imap.rb +++ b/lib/redmine/imap.rb @@ -48,9 +48,15 @@ def check(imap_options = {}, options = {}) def connect_imap(imap_options) host = imap_options[:host] || '127.0.0.1' port = imap_options[:port] || '143' - ssl = imap_options[:ssl] - ssl_verification = imap_options[:ssl_verification] - imap = Net::IMAP.new(host, port, ssl, nil, ssl_verification) + verify_mode = imap_options[:ssl_verification] ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE + ssl_params = + if imap_options[:ssl] + { verify_mode: } + else + false + end + + imap = Net::IMAP.new(host, port:, ssl: ssl_params) imap.login(imap_options[:username], imap_options[:password]) unless imap_options[:username].nil? From 662cb6558f3d316ff7ce40b132a52dab8201d135 Mon Sep 17 00:00:00 2001 From: Christophe Bliard Date: Fri, 26 Jan 2024 18:20:30 +0100 Subject: [PATCH 3/6] [52384] Avoid updating ancestor twice Processing ancestor twice leads to "Stale record" errors. It happened in this scenario (see Bug #52384): when creating the child, its attributes trigger a parent rescheduling. Once done, the parent is part of the dependent results of the rescheduling, and as all results (normal + dependent) are then processed by UpdateAncestorsService, the parent gets processed twice: a first time when the child is processed, and a second time when the parent is processed. As the parent has been updated the first time, the second parent update will fail because this parent instance is stale. Solution is to store ids of already updated work packages, and skip the update for the ones having already been updated. --- .../work_packages/shared/update_ancestors.rb | 9 ++++- .../create_service_integration_spec.rb | 32 +++++++++++++--- spec/support/table_helpers/column.rb | 2 + spec/workers/copy_project_job_spec.rb | 38 +++++++++++++++++++ 4 files changed, 74 insertions(+), 7 deletions(-) diff --git a/app/services/work_packages/shared/update_ancestors.rb b/app/services/work_packages/shared/update_ancestors.rb index 21d11eff700f..5d673b7a2b54 100644 --- a/app/services/work_packages/shared/update_ancestors.rb +++ b/app/services/work_packages/shared/update_ancestors.rb @@ -51,8 +51,13 @@ def update_ancestors_all_attributes(work_packages) end def update_each_ancestor(work_packages, changes) - work_packages.map do |wp| - inherit_to_ancestors(wp, changes) + updated_work_package_ids = Set.new + work_packages.filter_map do |wp| + next if updated_work_package_ids.include?(wp.id) + + result = inherit_to_ancestors(wp, changes) + updated_work_package_ids = updated_work_package_ids.merge(result.all_results.map(&:id)) + result end end diff --git a/spec/services/work_packages/create_service_integration_spec.rb b/spec/services/work_packages/create_service_integration_spec.rb index 0ae7bdf11721..11903ae92cdd 100644 --- a/spec/services/work_packages/create_service_integration_spec.rb +++ b/spec/services/work_packages/create_service_integration_spec.rb @@ -34,11 +34,7 @@ end let(:role) do create(:project_role, - permissions:) - end - - let(:permissions) do - %i(view_work_packages add_work_packages manage_subtasks) + permissions: %i[view_work_packages add_work_packages manage_subtasks]) end let(:type) do @@ -51,6 +47,7 @@ let(:project) { create(:project, types: [type, default_type]) } let(:parent) do create(:work_package, + subject: 'parent', project:, type:) end @@ -167,5 +164,30 @@ .to eql result.result end end + + describe 'with a child creation with both dates and work' do + let(:start_date) { Date.current } + let(:due_date) { start_date + 3.days } + let(:attributes) do + { + subject: 'child', + project:, + parent:, + estimated_hours: 5, + start_date:, + due_date: + } + end + + it 'correctly updates the parent values' do + expect(service_result) + .to be_success + + parent.reload + expect(parent.derived_estimated_hours).to eq(5) + expect(parent.start_date).to eq(start_date) + expect(parent.due_date).to eq(due_date) + end + end end end diff --git a/spec/support/table_helpers/column.rb b/spec/support/table_helpers/column.rb index a7e5c2b6ae9a..48d1184f351e 100644 --- a/spec/support/table_helpers/column.rb +++ b/spec/support/table_helpers/column.rb @@ -52,6 +52,8 @@ def self.for(header) Duration.new(header:, attribute: :remaining_hours) when /derived remaining work/i Duration.new(header:, attribute: :derived_remaining_hours) + when /end date/i + Generic.new(header:, attribute: :due_date) when /subject/ Subject.new(header:) when /hierarchy/ diff --git a/spec/workers/copy_project_job_spec.rb b/spec/workers/copy_project_job_spec.rb index 763ede6554b7..35b5841f7bcd 100644 --- a/spec/workers/copy_project_job_spec.rb +++ b/spec/workers/copy_project_job_spec.rb @@ -188,6 +188,44 @@ end end + context 'when project has work package hierarchies with derived values' do + shared_let(:source_project) { create(:project, name: 'Source project') } + + before_all do + set_factory_default(:project, source_project) + set_factory_default(:project_with_types, source_project) + end + + let(:admin) { create(:admin) } + let(:params) { { name: 'Copy', identifier: 'copy' } } + + let_work_packages(<<~TABLE) + hierarchy | work | start date | end date + parent | 1h | 2024-01-23 | 2024-01-26 + child | 3h | 2024-01-23 | 2024-01-26 + TABLE + + before do + WorkPackages::UpdateAncestorsService + .new(user: admin, work_package: child) + .call(%i[estimated_hours remaining_hours ignore_non_working_days]) + end + + it 'copies the project without any errord (Bug #52384)' do + allow(OpenProject.logger).to receive(:error) + + copy_job = described_class.new + copy_job.perform user_id: admin.id, + source_project_id: source_project.id, + target_project_params: params, + associations_to_copy: [:work_packages] + + expect(copy_job.job_status.status).to eq 'success' + expect(copy_job.errors).to be_empty + expect(OpenProject.logger).not_to have_received(:error) + end + end + describe 'perform' do let(:project) { create(:project, public: false) } let(:user) { create(:user) } From 3ea9016040db1e64123995dee21ba230aa814528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Mon, 29 Jan 2024 10:30:12 +0100 Subject: [PATCH 4/6] Remove unused event lookup service --- .../planner/event-view-lookup.service.ts | 123 ------------------ .../planner/team-planner.component.ts | 48 ++----- 2 files changed, 14 insertions(+), 157 deletions(-) delete mode 100644 frontend/src/app/features/team-planner/team-planner/planner/event-view-lookup.service.ts diff --git a/frontend/src/app/features/team-planner/team-planner/planner/event-view-lookup.service.ts b/frontend/src/app/features/team-planner/team-planner/planner/event-view-lookup.service.ts deleted file mode 100644 index 94612f914906..000000000000 --- a/frontend/src/app/features/team-planner/team-planner/planner/event-view-lookup.service.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { - EmbeddedViewRef, - Injectable, - OnDestroy, - TemplateRef, - ViewContainerRef, -} from '@angular/core'; -import { debugLog } from 'core-app/shared/helpers/debug_output'; - -/** - * View lookup service for injecting angular templates - * as fullcalendar event content. - * - * Based on the suggestion from Daniel Goldsmith - * in https://github.com/fullcalendar/fullcalendar-angular/issues/204 - * - */ -@Injectable() -export class EventViewLookupService implements OnDestroy { - /** Active templates currently rendered */ - private readonly activeViews = new Map>(); - - /** Remember detached views to be destroyed on destroyAll */ - private readonly detachedViews:EmbeddedViewRef[] = []; - - constructor(private viewContainerRef:ViewContainerRef) { - } - - /** - * Gets the view for the given ID, or creates one if there isn't one - * already. The template's context is set (or updated to, if the - * view has already been created) the given context values. - * @param template The template ref (get this from a @ViewChild of an - * ) - * @param id The unique ID for this instance of the view. Use this so that - * you don't keep around views for the same event. - * @param context The available variables for the . For - * example, if it looks like this: then - * your context should be an object with a `value` key. - */ - getView( - template:TemplateRef, id:string, context:unknown, - ):EmbeddedViewRef { - let view = this.activeViews.get(id); - if (view) { - debugLog('Returning active view %O', id); - view.detectChanges(); - return view; - } - - // Create a new view and move to active - debugLog('CREATING new view %O', id); - view = this.viewContainerRef.createEmbeddedView(template, context); - this.activeViews.set(id, view); - view.detectChanges(); - - return view; - } - - ngOnDestroy():void { - this.destroyAll(); - } - - /** - * Call this method if all views need to be cleaned up. This will happen - * when your parent component is destroyed (e.g., in ngOnDestroy), - * but it may also be needed if you are clearing just the area where the - * views have been placed. - */ - public destroyAll():void { - debugLog('Destroying all views'); - - Array - .from(this.activeViews.values()) - .forEach(this.destroyView.bind(this)); - - debugLog('Destroying %O active views', this.activeViews.size); - this.activeViews.clear(); - - this.destroyDetached(); - } - - /** - * Call this method if you want to clean detached views. - * This is safe to call outside of drag & drop operations. - * - */ - public destroyDetached():void { - debugLog('Destroying %O detached views', this.detachedViews.length); - - while (this.detachedViews.length) { - this.destroyView(this.detachedViews.pop() as EmbeddedViewRef); - } - } - - /** - * Mark a view to be destroyed. - * It will only be destroyed once +destroyAll+ is called. - * - * Ensure that destroyAll is called when, e.g., refreshing the calendar. - * - * @param id View ID - */ - public markForDestruction(id:string):void { - const view = this.activeViews.get(id); - if (!view) { - return; - } - - debugLog('Marking view %O to be destroyed', id); - this.activeViews.delete(id); - this.detachedViews.push(view); - } - - private destroyView(view:EmbeddedViewRef) { - const index = this.viewContainerRef.indexOf(view); - if (index !== -1) { - this.viewContainerRef.remove(index); - } - - view.destroy(); - } -} diff --git a/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts b/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts index 108e5ea5cf19..eaa450035e44 100644 --- a/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts +++ b/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts @@ -37,18 +37,8 @@ import { TemplateRef, ViewChild, } from '@angular/core'; -import { - CalendarOptions, - DateSelectArg, - EventApi, - EventDropArg, - EventInput, -} from '@fullcalendar/core'; -import { - BehaviorSubject, - combineLatest, - Subject, -} from 'rxjs'; +import { CalendarOptions, DateSelectArg, EventApi, EventDropArg, EventInput } from '@fullcalendar/core'; +import { BehaviorSubject, combineLatest, Subject } from 'rxjs'; import { debounceTime, distinctUntilChanged, @@ -73,29 +63,31 @@ import interactionPlugin, { import { FullCalendarComponent } from '@fullcalendar/angular'; import { I18nService } from 'core-app/core/i18n/i18n.service'; import { ConfigurationService } from 'core-app/core/config/configuration.service'; -import { EventViewLookupService } from 'core-app/features/team-planner/team-planner/planner/event-view-lookup.service'; -import { WorkPackageViewFiltersService } from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-filters.service'; +import { + WorkPackageViewFiltersService, +} from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-filters.service'; import { IsolatedQuerySpace } from 'core-app/features/work-packages/directives/query-space/isolated-query-space'; import { CurrentProjectService } from 'core-app/core/current-project/current-project.service'; import { splitViewRoute } from 'core-app/features/work-packages/routing/split-view-routes.helper'; import { QueryFilterInstanceResource } from 'core-app/features/hal/resources/query-filter-instance-resource'; import { PrincipalsResourceService } from 'core-app/core/state/principals/principals.service'; -import { - ApiV3ListFilter, - ApiV3ListParameters, -} from 'core-app/core/apiv3/paths/apiv3-list-resource.interface'; +import { ApiV3ListFilter, ApiV3ListParameters } from 'core-app/core/apiv3/paths/apiv3-list-resource.interface'; import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource'; import { HalResource } from 'core-app/features/hal/resources/hal-resource'; import { UntilDestroyedMixin } from 'core-app/shared/helpers/angular/until-destroyed.mixin'; import { OpCalendarService } from 'core-app/features/calendar/op-calendar.service'; -import { HalResourceEditingService } from 'core-app/shared/components/fields/edit/services/hal-resource-editing.service'; +import { + HalResourceEditingService, +} from 'core-app/shared/components/fields/edit/services/hal-resource-editing.service'; import { HalResourceNotificationService } from 'core-app/features/hal/services/hal-resource-notification.service'; import { SchemaCacheService } from 'core-app/core/schemas/schema-cache.service'; import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service'; import { CalendarDragDropService } from 'core-app/features/team-planner/team-planner/calendar-drag-drop.service'; import { StatusResource } from 'core-app/features/hal/resources/status-resource'; import { ResourceChangeset } from 'core-app/shared/components/fields/changeset/resource-changeset'; -import { KeepTabService } from 'core-app/features/work-packages/components/wp-single-view-tabs/keep-tab/keep-tab.service'; +import { + KeepTabService, +} from 'core-app/features/work-packages/components/wp-single-view-tabs/keep-tab/keep-tab.service'; import { HalError } from 'core-app/features/hal/services/hal-error'; import { ActionsService } from 'core-app/core/state/actions/actions.service'; import { @@ -104,10 +96,7 @@ import { teamPlannerPageRefresh, } from 'core-app/features/team-planner/team-planner/planner/team-planner.actions'; import { imagePath } from 'core-app/shared/helpers/images/path-helper'; -import { - skeletonEvents, - skeletonResources, -} from './loading-skeleton-data'; +import { skeletonEvents, skeletonResources } from './loading-skeleton-data'; import { CapabilitiesResourceService } from 'core-app/core/state/capabilities/capabilities.service'; import { ICapability } from 'core-app/core/state/capabilities/capability.model'; import { ToastService } from 'core-app/shared/components/toaster/toast.service'; @@ -118,10 +107,7 @@ import { RawOptionsFromRefiners } from '@fullcalendar/core/internal'; import { ViewOptionRefiners } from '@fullcalendar/common'; import { ResourceApi } from '@fullcalendar/resource'; import { DeviceService } from 'core-app/core/browser/device.service'; -import { - EffectCallback, - registerEffectCallbacks, -} from 'core-app/core/state/effects/effect-handler.decorator'; +import { EffectCallback, registerEffectCallbacks } from 'core-app/core/state/effects/effect-handler.decorator'; import { addBackgroundEvents, removeBackgroundEvents, @@ -136,9 +122,6 @@ export type TeamPlannerViewOptions = { [K in TeamPlannerViewOptionKey]:RawOption templateUrl: './team-planner.component.html', styleUrls: ['./team-planner.component.sass'], changeDetection: ChangeDetectionStrategy.OnPush, - providers: [ - EventViewLookupService, - ], }) export class TeamPlannerComponent extends UntilDestroyedMixin implements OnInit, OnDestroy { @ViewChild(FullCalendarComponent) ucCalendar:FullCalendarComponent; @@ -377,7 +360,6 @@ export class TeamPlannerComponent extends UntilDestroyedMixin implements OnInit, private wpTableFilters:WorkPackageViewFiltersService, private querySpace:IsolatedQuerySpace, private currentProject:CurrentProjectService, - private viewLookup:EventViewLookupService, private I18n:I18nService, readonly injector:Injector, readonly calendar:OpCalendarService, @@ -602,8 +584,6 @@ export class TeamPlannerComponent extends UntilDestroyedMixin implements OnInit, ([workPackages, projectAssignables]) => { const events = this.mapToCalendarEvents(workPackages.elements, projectAssignables); - this.viewLookup.destroyDetached(); - this.removeExternalEvents(); successCallback(events); From 320a874c07ca02ed280e8846d61831d20f0c10e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Mon, 29 Jan 2024 10:39:11 +0100 Subject: [PATCH 5/6] Increase calendar requested items and fix warning display https://community.openproject.org/work_packages/50895 --- .../op-work-packages-calendar.service.ts | 39 +++++++++++-------- .../planner/team-planner.component.ts | 2 + 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/frontend/src/app/features/calendar/op-work-packages-calendar.service.ts b/frontend/src/app/features/calendar/op-work-packages-calendar.service.ts index ffc68def7cd4..67c9b35811c4 100644 --- a/frontend/src/app/features/calendar/op-work-packages-calendar.service.ts +++ b/frontend/src/app/features/calendar/op-work-packages-calendar.service.ts @@ -1,7 +1,4 @@ -import { - Injectable, - Injector, -} from '@angular/core'; +import { Injectable, Injector } from '@angular/core'; import { CalendarOptions, DatesSetArg, @@ -22,11 +19,10 @@ import { splitViewRoute } from 'core-app/features/work-packages/routing/split-vi import { StateService } from '@uirouter/angular'; import { WorkPackageCollectionResource } from 'core-app/features/hal/resources/wp-collection-resource'; import { ToastService } from 'core-app/shared/components/toaster/toast.service'; +import { firstValueFrom, Observable } from 'rxjs'; import { - firstValueFrom, - Observable, -} from 'rxjs'; -import { WorkPackageViewFiltersService } from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-filters.service'; + WorkPackageViewFiltersService, +} from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-filters.service'; import { WorkPackagesListService } from 'core-app/features/work-packages/components/wp-list/wp-list.service'; import { IsolatedQuerySpace } from 'core-app/features/work-packages/directives/query-space/isolated-query-space'; import { UntilDestroyedMixin } from 'core-app/shared/helpers/angular/until-destroyed.mixin'; @@ -40,19 +36,26 @@ import { import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service'; import { UIRouterGlobals } from '@uirouter/core'; import { TimezoneService } from 'core-app/core/datetime/timezone.service'; -import { WorkPackagesListChecksumService } from 'core-app/features/work-packages/components/wp-list/wp-list-checksum.service'; import { - EventReceiveArg, - EventResizeDoneArg, -} from '@fullcalendar/interaction'; -import { HalResourceEditingService } from 'core-app/shared/components/fields/edit/services/hal-resource-editing.service'; + WorkPackagesListChecksumService, +} from 'core-app/features/work-packages/components/wp-list/wp-list-checksum.service'; +import { EventReceiveArg, EventResizeDoneArg } from '@fullcalendar/interaction'; +import { + HalResourceEditingService, +} from 'core-app/shared/components/fields/edit/services/hal-resource-editing.service'; import { ResourceChangeset } from 'core-app/shared/components/fields/changeset/resource-changeset'; import * as moment from 'moment'; -import { WorkPackageViewSelectionService } from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-selection.service'; +import { + WorkPackageViewSelectionService, +} from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-selection.service'; import { isClickedWithModifier } from 'core-app/shared/helpers/link-handling/link-handling'; -import { uiStateLinkClass } from 'core-app/features/work-packages/components/wp-fast-table/builders/ui-state-link-builder'; +import { + uiStateLinkClass, +} from 'core-app/features/work-packages/components/wp-fast-table/builders/ui-state-link-builder'; import { debugLog } from 'core-app/shared/helpers/debug_output'; -import { WorkPackageViewContextMenu } from 'core-app/shared/components/op-context-menu/wp-context-menu/wp-view-context-menu.directive'; +import { + WorkPackageViewContextMenu, +} from 'core-app/shared/components/op-context-menu/wp-context-menu/wp-view-context-menu.directive'; import { OPContextMenuService } from 'core-app/shared/components/op-context-menu/op-context-menu.service'; import { OpCalendarService } from 'core-app/features/calendar/op-calendar.service'; import { WeekdayService } from 'core-app/core/days/weekday.service'; @@ -71,7 +74,7 @@ interface CalendarOptionsWithDayGrid extends CalendarOptions { @Injectable() export class OpWorkPackagesCalendarService extends UntilDestroyedMixin { - static MAX_DISPLAYED = 100; + static MAX_DISPLAYED = 500; tooManyResultsText:string|null; @@ -207,6 +210,8 @@ export class OpWorkPackagesCalendarService extends UntilDestroyedMixin { ...(oldQueryProps.f as QueryPropsFilter[]).filter((filter:QueryPropsFilter) => filter.n !== 'datesInterval'), OpWorkPackagesCalendarService.dateFilter(startDate, endDate), ], + pp: OpWorkPackagesCalendarService.MAX_DISPLAYED, + pa: 1, }; queryProps = JSON.stringify(newQueryProps); diff --git a/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts b/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts index eaa450035e44..2755041a09eb 100644 --- a/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts +++ b/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts @@ -584,6 +584,8 @@ export class TeamPlannerComponent extends UntilDestroyedMixin implements OnInit, ([workPackages, projectAssignables]) => { const events = this.mapToCalendarEvents(workPackages.elements, projectAssignables); + this.workPackagesCalendar.warnOnTooManyResults(workPackages); + this.removeExternalEvents(); successCallback(events); From 3c19f31ddb24851b7cff6ab388624b3f98e9378a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Mon, 29 Jan 2024 10:24:34 +0100 Subject: [PATCH 6/6] Allow mentioning to happen on new work packages https://community.openproject.org/work_packages/52298 --- .../src/app/core/path-helper/apiv3-paths.ts | 14 +- frontend/src/vendor/ckeditor/ckeditor.js | 142326 +-------------- frontend/src/vendor/ckeditor/ckeditor.js.map | 2 +- .../src/vendor/ckeditor/translations/af.js | 2 +- .../src/vendor/ckeditor/translations/ar.js | 2 +- .../src/vendor/ckeditor/translations/ast.js | 2 +- .../src/vendor/ckeditor/translations/az.js | 2 +- .../src/vendor/ckeditor/translations/bg.js | 2 +- .../src/vendor/ckeditor/translations/bn.js | 2 +- .../src/vendor/ckeditor/translations/bs.js | 2 +- .../src/vendor/ckeditor/translations/ca.js | 2 +- .../src/vendor/ckeditor/translations/cs.js | 2 +- .../src/vendor/ckeditor/translations/da.js | 2 +- .../src/vendor/ckeditor/translations/de-ch.js | 2 +- .../src/vendor/ckeditor/translations/de.js | 2 +- .../src/vendor/ckeditor/translations/el.js | 2 +- .../src/vendor/ckeditor/translations/en-au.js | 2 +- .../src/vendor/ckeditor/translations/en-gb.js | 2 +- .../src/vendor/ckeditor/translations/eo.js | 2 +- .../src/vendor/ckeditor/translations/es-co.js | 2 +- .../src/vendor/ckeditor/translations/es.js | 2 +- .../src/vendor/ckeditor/translations/et.js | 2 +- .../src/vendor/ckeditor/translations/eu.js | 2 +- .../src/vendor/ckeditor/translations/fa.js | 2 +- .../src/vendor/ckeditor/translations/fi.js | 2 +- .../src/vendor/ckeditor/translations/fr.js | 2 +- .../src/vendor/ckeditor/translations/gl.js | 2 +- .../src/vendor/ckeditor/translations/gu.js | 2 +- .../src/vendor/ckeditor/translations/he.js | 2 +- .../src/vendor/ckeditor/translations/hi.js | 2 +- .../src/vendor/ckeditor/translations/hr.js | 2 +- .../src/vendor/ckeditor/translations/hu.js | 2 +- .../src/vendor/ckeditor/translations/id.js | 2 +- .../src/vendor/ckeditor/translations/it.js | 2 +- .../src/vendor/ckeditor/translations/ja.js | 2 +- .../src/vendor/ckeditor/translations/jv.js | 2 +- .../src/vendor/ckeditor/translations/km.js | 2 +- .../src/vendor/ckeditor/translations/kn.js | 2 +- .../src/vendor/ckeditor/translations/ko.js | 2 +- .../src/vendor/ckeditor/translations/ku.js | 2 +- .../src/vendor/ckeditor/translations/lt.js | 2 +- .../src/vendor/ckeditor/translations/lv.js | 2 +- .../src/vendor/ckeditor/translations/ms.js | 2 +- .../src/vendor/ckeditor/translations/nb.js | 2 +- .../src/vendor/ckeditor/translations/ne.js | 2 +- .../src/vendor/ckeditor/translations/nl.js | 2 +- .../src/vendor/ckeditor/translations/no.js | 2 +- .../src/vendor/ckeditor/translations/oc.js | 2 +- .../src/vendor/ckeditor/translations/pl.js | 2 +- .../src/vendor/ckeditor/translations/pt-br.js | 2 +- .../src/vendor/ckeditor/translations/pt.js | 2 +- .../src/vendor/ckeditor/translations/ro.js | 2 +- .../src/vendor/ckeditor/translations/ru.js | 2 +- .../src/vendor/ckeditor/translations/si.js | 2 +- .../src/vendor/ckeditor/translations/sk.js | 2 +- .../src/vendor/ckeditor/translations/sl.js | 2 +- .../src/vendor/ckeditor/translations/sq.js | 2 +- .../vendor/ckeditor/translations/sr-latn.js | 2 +- .../src/vendor/ckeditor/translations/sr.js | 2 +- .../src/vendor/ckeditor/translations/sv.js | 2 +- .../src/vendor/ckeditor/translations/th.js | 2 +- .../src/vendor/ckeditor/translations/tk.js | 2 +- .../src/vendor/ckeditor/translations/tr.js | 2 +- .../src/vendor/ckeditor/translations/tt.js | 2 +- .../src/vendor/ckeditor/translations/ug.js | 2 +- .../src/vendor/ckeditor/translations/uk.js | 2 +- .../src/vendor/ckeditor/translations/ur.js | 2 +- .../src/vendor/ckeditor/translations/uz.js | 2 +- .../src/vendor/ckeditor/translations/vi.js | 2 +- .../src/vendor/ckeditor/translations/zh-cn.js | 2 +- .../src/vendor/ckeditor/translations/zh.js | 2 +- 71 files changed, 83 insertions(+), 142395 deletions(-) diff --git a/frontend/src/app/core/path-helper/apiv3-paths.ts b/frontend/src/app/core/path-helper/apiv3-paths.ts index 14db6aa4c454..8a3bf707569f 100644 --- a/frontend/src/app/core/path-helper/apiv3-paths.ts +++ b/frontend/src/app/core/path-helper/apiv3-paths.ts @@ -1,4 +1,6 @@ import { ApiV3FilterBuilder } from 'core-app/shared/helpers/api-v3/api-v3-filter-builder'; +import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource'; +import { HalResource } from 'core-app/features/hal/resources/hal-resource'; export class ApiV3Paths { readonly apiV3Base:string; @@ -35,12 +37,18 @@ export class ApiV3Paths { * https://github.com/opf/commonmark-ckeditor-build/ * */ - public principals(workPackageId:string|number, term:string|null) { + public principals(workPackage:WorkPackageResource, term:string|null) { const filters:ApiV3FilterBuilder = new ApiV3FilterBuilder(); // Only real and activated users: filters.add('status', '!', ['3']); - // that are members of that project: - filters.add('mentionable_on_work_package', '=', [workPackageId.toString()]); + + if (!workPackage.id || workPackage.id === 'new') { + // that are members of that project: + filters.add('member', '=', [(workPackage.project as HalResource).id as string]); + } else { + // that are mentionable on the work package + filters.add('mentionable_on_work_package', '=', [workPackage.id.toString()]); + } // That are users: filters.add('type', '=', ['User', 'Group']); diff --git a/frontend/src/vendor/ckeditor/ckeditor.js b/frontend/src/vendor/ckeditor/ckeditor.js index 8325f7b8206d..924341b9c23b 100644 --- a/frontend/src/vendor/ckeditor/ckeditor.js +++ b/frontend/src/vendor/ckeditor/ckeditor.js @@ -1,142327 +1,7 @@ -(function(d){ const l = d['en'] = d['en'] || {}; l.dictionary=Object.assign( l.dictionary||{}, {"%0 of %1":"%0 of %1","Align cell text to the bottom":"Align cell text to the bottom","Align cell text to the center":"Align cell text to the center","Align cell text to the left":"Align cell text to the left","Align cell text to the middle":"Align cell text to the middle","Align cell text to the right":"Align cell text to the right","Align cell text to the top":"Align cell text to the top","Align table to the left":"Align table to the left","Align table to the right":"Align table to the right",Alignment:"Alignment",Aquamarine:"Aquamarine",Background:"Background",Black:"Black","Block quote":"Block quote",Blue:"Blue",Bold:"Bold",Border:"Border","Break text":"Break text","Bulleted List":"Bulleted List","Bulleted list styles toolbar":"Bulleted list styles toolbar",Cancel:"Cancel","Cannot upload file:":"Cannot upload file:","Caption for image: %0":"Caption for image: %0","Caption for the image":"Caption for the image","Cell properties":"Cell properties","Center table":"Center table","Centered image":"Centered image","Change image text alternative":"Change image text alternative","Choose heading":"Choose heading",Circle:"Circle",Code:"Code",Color:"Color","Color picker":"Color picker",Column:"Column",Dashed:"Dashed",Decimal:"Decimal","Decimal with leading zero":"Decimal with leading zero","Delete column":"Delete column","Delete row":"Delete row","Dim grey":"Dim grey",Dimensions:"Dimensions",Disc:"Disc",Dotted:"Dotted",Double:"Double",Downloadable:"Downloadable","Dropdown toolbar":"Dropdown toolbar","Edit block":"Edit block","Edit link":"Edit link","Editor block content toolbar":"Editor block content toolbar","Editor contextual toolbar":"Editor contextual toolbar","Editor editing area: %0":"Editor editing area: %0","Editor toolbar":"Editor toolbar","Enter image caption":"Enter image caption","Enter table caption":"Enter table caption","Full size image":"Full size image",Green:"Green",Grey:"Grey",Groove:"Groove","Header column":"Header column","Header row":"Header row",Heading:"Heading","Heading 1":"Heading 1","Heading 2":"Heading 2","Heading 3":"Heading 3","Heading 4":"Heading 4","Heading 5":"Heading 5","Heading 6":"Heading 6",Height:"Height",HEX:"HEX","Horizontal text alignment toolbar":"Horizontal text alignment toolbar","Image resize list":"Image resize list","Image toolbar":"Image toolbar","image widget":"image widget","In line":"In line",Insert:"Insert","Insert column left":"Insert column left","Insert column right":"Insert column right","Insert image":"Insert image","Insert image via URL":"Insert image via URL","Insert paragraph after block":"Insert paragraph after block","Insert paragraph before block":"Insert paragraph before block","Insert row above":"Insert row above","Insert row below":"Insert row below","Insert table":"Insert table",Inset:"Inset",Italic:"Italic","Justify cell text":"Justify cell text","Left aligned image":"Left aligned image","Light blue":"Light blue","Light green":"Light green","Light grey":"Light grey",Link:"Link","Link image":"Link image","Link URL":"Link URL","List properties":"List properties","Lower-latin":"Lower-latin","Lower–roman":"Lower–roman","Merge cell down":"Merge cell down","Merge cell left":"Merge cell left","Merge cell right":"Merge cell right","Merge cell up":"Merge cell up","Merge cells":"Merge cells",Next:"Next",None:"None","Numbered List":"Numbered List","Numbered list styles toolbar":"Numbered list styles toolbar","Open in a new tab":"Open in a new tab","Open link in new tab":"Open link in new tab",Orange:"Orange",Original:"Original",Outset:"Outset",Padding:"Padding",Paragraph:"Paragraph","Press Enter to type after or press Shift + Enter to type before the widget":"Press Enter to type after or press Shift + Enter to type before the widget",Previous:"Previous",Purple:"Purple",Red:"Red",Redo:"Redo","Remove color":"Remove color","Resize image":"Resize image","Resize image to %0":"Resize image to %0","Resize image to the original size":"Resize image to the original size","Restore default":"Restore default","Reversed order":"Reversed order","Rich Text Editor":"Rich Text Editor","Rich Text Editor. Editing area: %0":"Rich Text Editor. Editing area: %0",Ridge:"Ridge","Right aligned image":"Right aligned image",Row:"Row",Save:"Save","Select all":"Select all","Select column":"Select column","Select row":"Select row","Show more items":"Show more items","Side image":"Side image",Solid:"Solid","Split cell horizontally":"Split cell horizontally","Split cell vertically":"Split cell vertically",Square:"Square","Start at":"Start at","Start index must be greater than 0.":"Start index must be greater than 0.",Strikethrough:"Strikethrough",Style:"Style",Subscript:"Subscript",Superscript:"Superscript","Table alignment toolbar":"Table alignment toolbar","Table cell text alignment":"Table cell text alignment","Table properties":"Table properties","Table toolbar":"Table toolbar","Text alternative":"Text alternative","The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\".":"The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\".","The value is invalid. Try \"10px\" or \"2em\" or simply \"2\".":"The value is invalid. Try \"10px\" or \"2em\" or simply \"2\".","This link has no URL":"This link has no URL","To-do List":"To-do List","Toggle caption off":"Toggle caption off","Toggle caption on":"Toggle caption on","Toggle the circle list style":"Toggle the circle list style","Toggle the decimal list style":"Toggle the decimal list style","Toggle the decimal with leading zero list style":"Toggle the decimal with leading zero list style","Toggle the disc list style":"Toggle the disc list style","Toggle the lower–latin list style":"Toggle the lower–latin list style","Toggle the lower–roman list style":"Toggle the lower–roman list style","Toggle the square list style":"Toggle the square list style","Toggle the upper–latin list style":"Toggle the upper–latin list style","Toggle the upper–roman list style":"Toggle the upper–roman list style",Turquoise:"Turquoise","Type or paste your content here.":"Type or paste your content here.","Type your title":"Type your title",Underline:"Underline",Undo:"Undo",Unlink:"Unlink",Update:"Update","Update image URL":"Update image URL","Upload failed":"Upload failed","Upload in progress":"Upload in progress","Upper-latin":"Upper-latin","Upper-roman":"Upper-roman","Vertical text alignment toolbar":"Vertical text alignment toolbar",White:"White","Widget toolbar":"Widget toolbar",Width:"Width","Wrap text":"Wrap text",Yellow:"Yellow"} );})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={})); +!function(e){const t=e.en=e.en||{};t.dictionary=Object.assign(t.dictionary||{},{"%0 of %1":"%0 of %1","Align cell text to the bottom":"Align cell text to the bottom","Align cell text to the center":"Align cell text to the center","Align cell text to the left":"Align cell text to the left","Align cell text to the middle":"Align cell text to the middle","Align cell text to the right":"Align cell text to the right","Align cell text to the top":"Align cell text to the top","Align table to the left":"Align table to the left","Align table to the right":"Align table to the right",Alignment:"Alignment",Aquamarine:"Aquamarine",Background:"Background",Black:"Black","Block quote":"Block quote",Blue:"Blue",Bold:"Bold",Border:"Border","Break text":"Break text","Bulleted List":"Bulleted List","Bulleted list styles toolbar":"Bulleted list styles toolbar",Cancel:"Cancel","Cannot upload file:":"Cannot upload file:","Caption for image: %0":"Caption for image: %0","Caption for the image":"Caption for the image","Cell properties":"Cell properties","Center table":"Center table","Centered image":"Centered image","Change image text alternative":"Change image text alternative","Choose heading":"Choose heading",Circle:"Circle",Code:"Code",Color:"Color","Color picker":"Color picker",Column:"Column",Dashed:"Dashed",Decimal:"Decimal","Decimal with leading zero":"Decimal with leading zero","Delete column":"Delete column","Delete row":"Delete row","Dim grey":"Dim grey",Dimensions:"Dimensions",Disc:"Disc",Dotted:"Dotted",Double:"Double",Downloadable:"Downloadable","Dropdown toolbar":"Dropdown toolbar","Edit block":"Edit block","Edit link":"Edit link","Editor block content toolbar":"Editor block content toolbar","Editor contextual toolbar":"Editor contextual toolbar","Editor editing area: %0":"Editor editing area: %0","Editor toolbar":"Editor toolbar","Enter image caption":"Enter image caption","Enter table caption":"Enter table caption","Full size image":"Full size image",Green:"Green",Grey:"Grey",Groove:"Groove","Header column":"Header column","Header row":"Header row",Heading:"Heading","Heading 1":"Heading 1","Heading 2":"Heading 2","Heading 3":"Heading 3","Heading 4":"Heading 4","Heading 5":"Heading 5","Heading 6":"Heading 6",Height:"Height",HEX:"HEX","Horizontal text alignment toolbar":"Horizontal text alignment toolbar","Image resize list":"Image resize list","Image toolbar":"Image toolbar","image widget":"image widget","In line":"In line",Insert:"Insert","Insert column left":"Insert column left","Insert column right":"Insert column right","Insert image":"Insert image","Insert image via URL":"Insert image via URL","Insert paragraph after block":"Insert paragraph after block","Insert paragraph before block":"Insert paragraph before block","Insert row above":"Insert row above","Insert row below":"Insert row below","Insert table":"Insert table",Inset:"Inset",Italic:"Italic","Justify cell text":"Justify cell text","Left aligned image":"Left aligned image","Light blue":"Light blue","Light green":"Light green","Light grey":"Light grey",Link:"Link","Link image":"Link image","Link URL":"Link URL","List properties":"List properties","Lower-latin":"Lower-latin","Lower–roman":"Lower–roman","Merge cell down":"Merge cell down","Merge cell left":"Merge cell left","Merge cell right":"Merge cell right","Merge cell up":"Merge cell up","Merge cells":"Merge cells",Next:"Next",None:"None","Numbered List":"Numbered List","Numbered list styles toolbar":"Numbered list styles toolbar","Open in a new tab":"Open in a new tab","Open link in new tab":"Open link in new tab",Orange:"Orange",Original:"Original",Outset:"Outset",Padding:"Padding",Paragraph:"Paragraph","Press Enter to type after or press Shift + Enter to type before the widget":"Press Enter to type after or press Shift + Enter to type before the widget",Previous:"Previous",Purple:"Purple",Red:"Red",Redo:"Redo","Remove color":"Remove color","Resize image":"Resize image","Resize image to %0":"Resize image to %0","Resize image to the original size":"Resize image to the original size","Restore default":"Restore default","Reversed order":"Reversed order","Rich Text Editor":"Rich Text Editor","Rich Text Editor. Editing area: %0":"Rich Text Editor. Editing area: %0",Ridge:"Ridge","Right aligned image":"Right aligned image",Row:"Row",Save:"Save","Select all":"Select all","Select column":"Select column","Select row":"Select row","Show more items":"Show more items","Side image":"Side image",Solid:"Solid","Split cell horizontally":"Split cell horizontally","Split cell vertically":"Split cell vertically",Square:"Square","Start at":"Start at","Start index must be greater than 0.":"Start index must be greater than 0.",Strikethrough:"Strikethrough",Style:"Style",Subscript:"Subscript",Superscript:"Superscript","Table alignment toolbar":"Table alignment toolbar","Table cell text alignment":"Table cell text alignment","Table properties":"Table properties","Table toolbar":"Table toolbar","Text alternative":"Text alternative",'The color is invalid. Try "#FF0000" or "rgb(255,0,0)" or "red".':'The color is invalid. Try "#FF0000" or "rgb(255,0,0)" or "red".','The value is invalid. Try "10px" or "2em" or simply "2".':'The value is invalid. Try "10px" or "2em" or simply "2".',"This link has no URL":"This link has no URL","To-do List":"To-do List","Toggle caption off":"Toggle caption off","Toggle caption on":"Toggle caption on","Toggle the circle list style":"Toggle the circle list style","Toggle the decimal list style":"Toggle the decimal list style","Toggle the decimal with leading zero list style":"Toggle the decimal with leading zero list style","Toggle the disc list style":"Toggle the disc list style","Toggle the lower–latin list style":"Toggle the lower–latin list style","Toggle the lower–roman list style":"Toggle the lower–roman list style","Toggle the square list style":"Toggle the square list style","Toggle the upper–latin list style":"Toggle the upper–latin list style","Toggle the upper–roman list style":"Toggle the upper–roman list style",Turquoise:"Turquoise","Type or paste your content here.":"Type or paste your content here.","Type your title":"Type your title",Underline:"Underline",Undo:"Undo",Unlink:"Unlink",Update:"Update","Update image URL":"Update image URL","Upload failed":"Upload failed","Upload in progress":"Upload in progress","Upper-latin":"Upper-latin","Upper-roman":"Upper-roman","Vertical text alignment toolbar":"Vertical text alignment toolbar",White:"White","Widget toolbar":"Widget toolbar",Width:"Width","Wrap text":"Wrap text",Yellow:"Yellow"})}(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={})), /*! - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. + * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md. */ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define([], factory); - else if(typeof exports === 'object') - exports["OPEditor"] = factory(); - else - root["OPEditor"] = factory(); -})(self, () => { -return /******/ (() => { // webpackBootstrap -/******/ var __webpack_modules__ = ({ - -/***/ "./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/augmentation.js": -/*!*******************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/augmentation.js ***! - \*******************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ - - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/index.js": -/*!************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/index.js ***! - \************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ UploadAdapter: () => (/* reexport safe */ _uploadadapter__WEBPACK_IMPORTED_MODULE_0__["default"]) -/* harmony export */ }); -/* harmony import */ var _uploadadapter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./uploadadapter */ "./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter.js"); -/* harmony import */ var _augmentation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./augmentation */ "./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/augmentation.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module adapter-ckfinder - */ - - - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter.js": -/*!********************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/uploadadapter.js ***! - \********************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ CKFinderUploadAdapter) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var ckeditor5_src_upload__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/upload */ "./node_modules/ckeditor5/src/upload.js"); -/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils */ "./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/utils.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/* globals XMLHttpRequest, FormData */ -/** - * @module adapter-ckfinder/uploadadapter - */ - - - -/** - * A plugin that enables file uploads in CKEditor 5 using the CKFinder server–side connector. - * - * See the {@glink features/file-management/ckfinder "CKFinder file manager integration"} guide to learn how to configure - * and use this feature as well as find out more about the full integration with the file manager - * provided by the {@link module:ckfinder/ckfinder~CKFinder} plugin. - * - * Check out the {@glink features/images/image-upload/image-upload comprehensive "Image upload overview"} guide to learn - * about other ways to upload images into CKEditor 5. - */ -class CKFinderUploadAdapter extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get requires() { - return [ckeditor5_src_upload__WEBPACK_IMPORTED_MODULE_1__.FileRepository]; - } - /** - * @inheritDoc - */ - static get pluginName() { - return 'CKFinderUploadAdapter'; - } - /** - * @inheritDoc - */ - init() { - const url = this.editor.config.get('ckfinder.uploadUrl'); - if (!url) { - return; - } - // Register CKFinderAdapter - this.editor.plugins.get(ckeditor5_src_upload__WEBPACK_IMPORTED_MODULE_1__.FileRepository).createUploadAdapter = loader => new UploadAdapter(loader, url, this.editor.t); - } -} -/** - * Upload adapter for CKFinder. - */ -class UploadAdapter { - /** - * Creates a new adapter instance. - */ - constructor(loader, url, t) { - this.loader = loader; - this.url = url; - this.t = t; - } - /** - * Starts the upload process. - * - * @see module:upload/filerepository~UploadAdapter#upload - */ - upload() { - return this.loader.file.then(file => { - return new Promise((resolve, reject) => { - this._initRequest(); - this._initListeners(resolve, reject, file); - this._sendRequest(file); - }); - }); - } - /** - * Aborts the upload process. - * - * @see module:upload/filerepository~UploadAdapter#abort - */ - abort() { - if (this.xhr) { - this.xhr.abort(); - } - } - /** - * Initializes the XMLHttpRequest object. - */ - _initRequest() { - const xhr = this.xhr = new XMLHttpRequest(); - xhr.open('POST', this.url, true); - xhr.responseType = 'json'; - } - /** - * Initializes XMLHttpRequest listeners. - * - * @param resolve Callback function to be called when the request is successful. - * @param reject Callback function to be called when the request cannot be completed. - * @param file File instance to be uploaded. - */ - _initListeners(resolve, reject, file) { - const xhr = this.xhr; - const loader = this.loader; - const t = this.t; - const genericError = t('Cannot upload file:') + ` ${file.name}.`; - xhr.addEventListener('error', () => reject(genericError)); - xhr.addEventListener('abort', () => reject()); - xhr.addEventListener('load', () => { - const response = xhr.response; - if (!response || !response.uploaded) { - return reject(response && response.error && response.error.message ? response.error.message : genericError); - } - resolve({ - default: response.url - }); - }); - // Upload progress when it's supported. - /* istanbul ignore else -- @preserve */ - if (xhr.upload) { - xhr.upload.addEventListener('progress', evt => { - if (evt.lengthComputable) { - loader.uploadTotal = evt.total; - loader.uploaded = evt.loaded; - } - }); - } - } - /** - * Prepares the data and sends the request. - * - * @param file File instance to be uploaded. - */ - _sendRequest(file) { - // Prepare form data. - const data = new FormData(); - data.append('upload', file); - data.append('ckCsrfToken', (0,_utils__WEBPACK_IMPORTED_MODULE_2__.getCsrfToken)()); - // Send request. - this.xhr.send(data); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/utils.js": -/*!************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-adapter-ckfinder/src/utils.js ***! - \************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ getCookie: () => (/* binding */ getCookie), -/* harmony export */ getCsrfToken: () => (/* binding */ getCsrfToken), -/* harmony export */ setCookie: () => (/* binding */ setCookie) -/* harmony export */ }); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/* globals window, document */ -/** - * @module adapter-ckfinder/utils - */ -const TOKEN_COOKIE_NAME = 'ckCsrfToken'; -const TOKEN_LENGTH = 40; -const tokenCharset = 'abcdefghijklmnopqrstuvwxyz0123456789'; -/** - * Returns the CSRF token value. The value is a hash stored in `document.cookie` - * under the `ckCsrfToken` key. The CSRF token can be used to secure the communication - * between the web browser and the CKFinder server. - */ -function getCsrfToken() { - let token = getCookie(TOKEN_COOKIE_NAME); - if (!token || token.length != TOKEN_LENGTH) { - token = generateToken(TOKEN_LENGTH); - setCookie(TOKEN_COOKIE_NAME, token); - } - return token; -} -/** - * Returns the value of the cookie with a given name or `null` if the cookie is not found. - */ -function getCookie(name) { - name = name.toLowerCase(); - const parts = document.cookie.split(';'); - for (const part of parts) { - const pair = part.split('='); - const key = decodeURIComponent(pair[0].trim().toLowerCase()); - if (key === name) { - return decodeURIComponent(pair[1]); - } - } - return null; -} -/** - * Sets the value of the cookie with a given name. - */ -function setCookie(name, value) { - document.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value) + ';path=/'; -} -/** - * Generates the CSRF token with the given length. - */ -function generateToken(length) { - let result = ''; - const randValues = new Uint8Array(length); - window.crypto.getRandomValues(randValues); - for (let j = 0; j < randValues.length; j++) { - const character = tokenCharset.charAt(randValues[j] % tokenCharset.length); - result += Math.random() > 0.5 ? character.toUpperCase() : character; - } - return result; -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-autoformat/src/augmentation.js": -/*!*************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-autoformat/src/augmentation.js ***! - \*************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ - - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-autoformat/src/autoformat.js": -/*!***********************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-autoformat/src/autoformat.js ***! - \***********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Autoformat) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var ckeditor5_src_typing__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/typing */ "./node_modules/ckeditor5/src/typing.js"); -/* harmony import */ var _blockautoformatediting__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./blockautoformatediting */ "./node_modules/@ckeditor/ckeditor5-autoformat/src/blockautoformatediting.js"); -/* harmony import */ var _inlineautoformatediting__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./inlineautoformatediting */ "./node_modules/@ckeditor/ckeditor5-autoformat/src/inlineautoformatediting.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ - - - - -/** - * Enables a set of predefined autoformatting actions. - * - * For a detailed overview, check the {@glink features/autoformat Autoformatting} feature guide - * and the {@glink api/autoformat package page}. - */ -class Autoformat extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get requires() { - return [ckeditor5_src_typing__WEBPACK_IMPORTED_MODULE_1__.Delete]; - } - /** - * @inheritDoc - */ - static get pluginName() { - return 'Autoformat'; - } - /** - * @inheritDoc - */ - afterInit() { - this._addListAutoformats(); - this._addBasicStylesAutoformats(); - this._addHeadingAutoformats(); - this._addBlockQuoteAutoformats(); - this._addCodeBlockAutoformats(); - this._addHorizontalLineAutoformats(); - } - /** - * Adds autoformatting related to the {@link module:list/list~List}. - * - * When typed: - * - `* ` or `- ` – A paragraph will be changed into a bulleted list. - * - `1. ` or `1) ` – A paragraph will be changed into a numbered list ("1" can be any digit or a list of digits). - * - `[] ` or `[ ] ` – A paragraph will be changed into a to-do list. - * - `[x] ` or `[ x ] ` – A paragraph will be changed into a checked to-do list. - */ - _addListAutoformats() { - const commands = this.editor.commands; - if (commands.get('bulletedList')) { - (0,_blockautoformatediting__WEBPACK_IMPORTED_MODULE_2__["default"])(this.editor, this, /^[*-]\s$/, 'bulletedList'); - } - if (commands.get('numberedList')) { - (0,_blockautoformatediting__WEBPACK_IMPORTED_MODULE_2__["default"])(this.editor, this, /^1[.|)]\s$/, 'numberedList'); - } - if (commands.get('todoList')) { - (0,_blockautoformatediting__WEBPACK_IMPORTED_MODULE_2__["default"])(this.editor, this, /^\[\s?\]\s$/, 'todoList'); - } - if (commands.get('checkTodoList')) { - (0,_blockautoformatediting__WEBPACK_IMPORTED_MODULE_2__["default"])(this.editor, this, /^\[\s?x\s?\]\s$/, () => { - this.editor.execute('todoList'); - this.editor.execute('checkTodoList'); - }); - } - } - /** - * Adds autoformatting related to the {@link module:basic-styles/bold~Bold}, - * {@link module:basic-styles/italic~Italic}, {@link module:basic-styles/code~Code} - * and {@link module:basic-styles/strikethrough~Strikethrough} - * - * When typed: - * - `**foobar**` – `**` characters are removed and `foobar` is set to bold, - * - `__foobar__` – `__` characters are removed and `foobar` is set to bold, - * - `*foobar*` – `*` characters are removed and `foobar` is set to italic, - * - `_foobar_` – `_` characters are removed and `foobar` is set to italic, - * - ``` `foobar` – ``` ` ``` characters are removed and `foobar` is set to code, - * - `~~foobar~~` – `~~` characters are removed and `foobar` is set to strikethrough. - */ - _addBasicStylesAutoformats() { - const commands = this.editor.commands; - if (commands.get('bold')) { - const boldCallback = getCallbackFunctionForInlineAutoformat(this.editor, 'bold'); - (0,_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_3__["default"])(this.editor, this, /(?:^|\s)(\*\*)([^*]+)(\*\*)$/g, boldCallback); - (0,_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_3__["default"])(this.editor, this, /(?:^|\s)(__)([^_]+)(__)$/g, boldCallback); - } - if (commands.get('italic')) { - const italicCallback = getCallbackFunctionForInlineAutoformat(this.editor, 'italic'); - // The italic autoformatter cannot be triggered by the bold markers, so we need to check the - // text before the pattern (e.g. `(?:^|[^\*])`). - (0,_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_3__["default"])(this.editor, this, /(?:^|\s)(\*)([^*_]+)(\*)$/g, italicCallback); - (0,_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_3__["default"])(this.editor, this, /(?:^|\s)(_)([^_]+)(_)$/g, italicCallback); - } - if (commands.get('code')) { - const codeCallback = getCallbackFunctionForInlineAutoformat(this.editor, 'code'); - (0,_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_3__["default"])(this.editor, this, /(`)([^`]+)(`)$/g, codeCallback); - } - if (commands.get('strikethrough')) { - const strikethroughCallback = getCallbackFunctionForInlineAutoformat(this.editor, 'strikethrough'); - (0,_inlineautoformatediting__WEBPACK_IMPORTED_MODULE_3__["default"])(this.editor, this, /(~~)([^~]+)(~~)$/g, strikethroughCallback); - } - } - /** - * Adds autoformatting related to {@link module:heading/heading~Heading}. - * - * It is using a number at the end of the command name to associate it with the proper trigger: - * - * * `heading` with a `heading1` value will be executed when typing `#`, - * * `heading` with a `heading2` value will be executed when typing `##`, - * * ... up to `heading6` for `######`. - */ - _addHeadingAutoformats() { - const command = this.editor.commands.get('heading'); - if (command) { - command.modelElements - .filter(name => name.match(/^heading[1-6]$/)) - .forEach(modelName => { - const level = modelName[7]; - const pattern = new RegExp(`^(#{${level}})\\s$`); - (0,_blockautoformatediting__WEBPACK_IMPORTED_MODULE_2__["default"])(this.editor, this, pattern, () => { - // Should only be active if command is enabled and heading style associated with pattern is inactive. - if (!command.isEnabled || command.value === modelName) { - return false; - } - this.editor.execute('heading', { value: modelName }); - }); - }); - } - } - /** - * Adds autoformatting related to {@link module:block-quote/blockquote~BlockQuote}. - * - * When typed: - * * `> ` – A paragraph will be changed to a block quote. - */ - _addBlockQuoteAutoformats() { - if (this.editor.commands.get('blockQuote')) { - (0,_blockautoformatediting__WEBPACK_IMPORTED_MODULE_2__["default"])(this.editor, this, /^>\s$/, 'blockQuote'); - } - } - /** - * Adds autoformatting related to {@link module:code-block/codeblock~CodeBlock}. - * - * When typed: - * - `` ``` `` – A paragraph will be changed to a code block. - */ - _addCodeBlockAutoformats() { - const editor = this.editor; - const selection = editor.model.document.selection; - if (editor.commands.get('codeBlock')) { - (0,_blockautoformatediting__WEBPACK_IMPORTED_MODULE_2__["default"])(editor, this, /^```$/, () => { - if (selection.getFirstPosition().parent.is('element', 'listItem')) { - return false; - } - this.editor.execute('codeBlock', { - usePreviousLanguageChoice: true - }); - }); - } - } - /** - * Adds autoformatting related to {@link module:horizontal-line/horizontalline~HorizontalLine}. - * - * When typed: - * - `` --- `` – Will be replaced with a horizontal line. - */ - _addHorizontalLineAutoformats() { - if (this.editor.commands.get('horizontalLine')) { - (0,_blockautoformatediting__WEBPACK_IMPORTED_MODULE_2__["default"])(this.editor, this, /^---$/, 'horizontalLine'); - } - } -} -/** - * Helper function for getting `inlineAutoformatEditing` callbacks that checks if command is enabled. - */ -function getCallbackFunctionForInlineAutoformat(editor, attributeKey) { - return (writer, rangesToFormat) => { - const command = editor.commands.get(attributeKey); - if (!command.isEnabled) { - return false; - } - const validRanges = editor.model.schema.getValidRanges(rangesToFormat, attributeKey); - for (const range of validRanges) { - writer.setAttribute(attributeKey, true, range); - } - // After applying attribute to the text, remove given attribute from the selection. - // This way user is able to type a text without attribute used by auto formatter. - writer.removeSelectionAttribute(attributeKey); - }; -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-autoformat/src/blockautoformatediting.js": -/*!***********************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-autoformat/src/blockautoformatediting.js ***! - \***********************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ blockAutoformatEditing) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/engine */ "./node_modules/ckeditor5/src/engine.js"); -/* harmony import */ var ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/utils */ "./node_modules/ckeditor5/src/utils.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ - - -/** - * The block autoformatting engine. It allows to format various block patterns. For example, - * it can be configured to turn a paragraph starting with `*` and followed by a space into a list item. - * - * The autoformatting operation is integrated with the undo manager, - * so the autoformatting step can be undone if the user's intention was not to format the text. - * - * See the {@link module:autoformat/blockautoformatediting~blockAutoformatEditing `blockAutoformatEditing`} documentation - * to learn how to create custom block autoformatters. You can also use - * the {@link module:autoformat/autoformat~Autoformat} feature which enables a set of default autoformatters - * (lists, headings, bold and italic). - * - * @module autoformat/blockautoformatediting - */ -/** - * Creates a listener triggered on {@link module:engine/model/document~Document#event:change:data `change:data`} event in the document. - * Calls the callback when inserted text matches the regular expression or the command name - * if provided instead of the callback. - * - * Examples of usage: - * - * To convert a paragraph into heading 1 when `- ` is typed, using just the command name: - * - * ```ts - * blockAutoformatEditing( editor, plugin, /^\- $/, 'heading1' ); - * ``` - * - * To convert a paragraph into heading 1 when `- ` is typed, using just the callback: - * - * ```ts - * blockAutoformatEditing( editor, plugin, /^\- $/, ( context ) => { - * const { match } = context; - * const headingLevel = match[ 1 ].length; - * - * editor.execute( 'heading', { - * formatId: `heading${ headingLevel }` - * } ); - * } ); - * ``` - * - * @param editor The editor instance. - * @param plugin The autoformat plugin instance. - * @param pattern The regular expression to execute on just inserted text. The regular expression is tested against the text - * from the beginning until the caret position. - * @param callbackOrCommand The callback to execute or the command to run when the text is matched. - * In case of providing the callback, it receives the following parameter: - * * match RegExp.exec() result of matching the pattern to inserted text. - */ -function blockAutoformatEditing(editor, plugin, pattern, callbackOrCommand) { - let callback; - let command = null; - if (typeof callbackOrCommand == 'function') { - callback = callbackOrCommand; - } - else { - // We assume that the actual command name was provided. - command = editor.commands.get(callbackOrCommand); - callback = () => { - editor.execute(callbackOrCommand); - }; - } - editor.model.document.on('change:data', (evt, batch) => { - if (command && !command.isEnabled || !plugin.isEnabled) { - return; - } - const range = (0,ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_1__.first)(editor.model.document.selection.getRanges()); - if (!range.isCollapsed) { - return; - } - if (batch.isUndo || !batch.isLocal) { - return; - } - const changes = Array.from(editor.model.document.differ.getChanges()); - const entry = changes[0]; - // Typing is represented by only a single change. - if (changes.length != 1 || entry.type !== 'insert' || entry.name != '$text' || entry.length != 1) { - return; - } - const blockToFormat = entry.position.parent; - // Block formatting should be disabled in codeBlocks (#5800). - if (blockToFormat.is('element', 'codeBlock')) { - return; - } - // Only list commands and custom callbacks can be applied inside a list. - if (blockToFormat.is('element', 'listItem') && - typeof callbackOrCommand !== 'function' && - !['numberedList', 'bulletedList', 'todoList'].includes(callbackOrCommand)) { - return; - } - // In case a command is bound, do not re-execute it over an existing block style which would result in a style removal. - // Instead, just drop processing so that autoformat trigger text is not lost. E.g. writing "# " in a level 1 heading. - if (command && command.value === true) { - return; - } - const firstNode = blockToFormat.getChild(0); - const firstNodeRange = editor.model.createRangeOn(firstNode); - // Range is only expected to be within or at the very end of the first text node. - if (!firstNodeRange.containsRange(range) && !range.end.isEqual(firstNodeRange.end)) { - return; - } - const match = pattern.exec(firstNode.data.substr(0, range.end.offset)); - // ...and this text node's data match the pattern. - if (!match) { - return; - } - // Use enqueueChange to create new batch to separate typing batch from the auto-format changes. - editor.model.enqueueChange(writer => { - // Matched range. - const start = writer.createPositionAt(blockToFormat, 0); - const end = writer.createPositionAt(blockToFormat, match[0].length); - const range = new ckeditor5_src_engine__WEBPACK_IMPORTED_MODULE_0__.LiveRange(start, end); - const wasChanged = callback({ match }); - // Remove matched text. - if (wasChanged !== false) { - writer.remove(range); - const selectionRange = editor.model.document.selection.getFirstRange(); - const blockRange = writer.createRangeIn(blockToFormat); - // If the block is empty and the document selection has been moved when - // applying formatting (e.g. is now in newly created block). - if (blockToFormat.isEmpty && !blockRange.isEqual(selectionRange) && !blockRange.containsRange(selectionRange, true)) { - writer.remove(blockToFormat); - } - } - range.detach(); - editor.model.enqueueChange(() => { - const deletePlugin = editor.plugins.get('Delete'); - deletePlugin.requestUndoOnBackspace(); - }); - }); - }); -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-autoformat/src/index.js": -/*!******************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-autoformat/src/index.js ***! - \******************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Autoformat: () => (/* reexport safe */ _autoformat__WEBPACK_IMPORTED_MODULE_0__["default"]) -/* harmony export */ }); -/* harmony import */ var _autoformat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./autoformat */ "./node_modules/@ckeditor/ckeditor5-autoformat/src/autoformat.js"); -/* harmony import */ var _augmentation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./augmentation */ "./node_modules/@ckeditor/ckeditor5-autoformat/src/augmentation.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module autoformat - */ - - - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-autoformat/src/inlineautoformatediting.js": -/*!************************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-autoformat/src/inlineautoformatediting.js ***! - \************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ inlineAutoformatEditing) -/* harmony export */ }); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * Enables autoformatting mechanism for a given {@link module:core/editor/editor~Editor}. - * - * It formats the matched text by applying the given model attribute or by running the provided formatting callback. - * On every {@link module:engine/model/document~Document#event:change:data data change} in the model document - * the autoformatting engine checks the text on the left of the selection - * and executes the provided action if the text matches given criteria (regular expression or callback). - * - * @param editor The editor instance. - * @param plugin The autoformat plugin instance. - * @param testRegexpOrCallback The regular expression or callback to execute on text. - * Provided regular expression *must* have three capture groups. The first and the third capture group - * should match opening and closing delimiters. The second capture group should match the text to format. - * - * ```ts - * // Matches the `**bold text**` pattern. - * // There are three capturing groups: - * // - The first to match the starting `**` delimiter. - * // - The second to match the text to format. - * // - The third to match the ending `**` delimiter. - * inlineAutoformatEditing( editor, plugin, /(\*\*)([^\*]+?)(\*\*)$/g, formatCallback ); - * ``` - * - * When a function is provided instead of the regular expression, it will be executed with the text to match as a parameter. - * The function should return proper "ranges" to delete and format. - * - * ```ts - * { - * remove: [ - * [ 0, 1 ], // Remove the first letter from the given text. - * [ 5, 6 ] // Remove the 6th letter from the given text. - * ], - * format: [ - * [ 1, 5 ] // Format all letters from 2nd to 5th. - * ] - * } - * ``` - * - * @param formatCallback A callback to apply actual formatting. - * It should return `false` if changes should not be applied (e.g. if a command is disabled). - * - * ```ts - * inlineAutoformatEditing( editor, plugin, /(\*\*)([^\*]+?)(\*\*)$/g, ( writer, rangesToFormat ) => { - * const command = editor.commands.get( 'bold' ); - * - * if ( !command.isEnabled ) { - * return false; - * } - * - * const validRanges = editor.model.schema.getValidRanges( rangesToFormat, 'bold' ); - * - * for ( let range of validRanges ) { - * writer.setAttribute( 'bold', true, range ); - * } - * } ); - * ``` - */ -function inlineAutoformatEditing(editor, plugin, testRegexpOrCallback, formatCallback) { - let regExp; - let testCallback; - if (testRegexpOrCallback instanceof RegExp) { - regExp = testRegexpOrCallback; - } - else { - testCallback = testRegexpOrCallback; - } - // A test callback run on changed text. - testCallback = testCallback || (text => { - let result; - const remove = []; - const format = []; - while ((result = regExp.exec(text)) !== null) { - // There should be full match and 3 capture groups. - if (result && result.length < 4) { - break; - } - let { index, '1': leftDel, '2': content, '3': rightDel } = result; - // Real matched string - there might be some non-capturing groups so we need to recalculate starting index. - const found = leftDel + content + rightDel; - index += result[0].length - found.length; - // Start and End offsets of delimiters to remove. - const delStart = [ - index, - index + leftDel.length - ]; - const delEnd = [ - index + leftDel.length + content.length, - index + leftDel.length + content.length + rightDel.length - ]; - remove.push(delStart); - remove.push(delEnd); - format.push([index + leftDel.length, index + leftDel.length + content.length]); - } - return { - remove, - format - }; - }); - editor.model.document.on('change:data', (evt, batch) => { - if (batch.isUndo || !batch.isLocal || !plugin.isEnabled) { - return; - } - const model = editor.model; - const selection = model.document.selection; - // Do nothing if selection is not collapsed. - if (!selection.isCollapsed) { - return; - } - const changes = Array.from(model.document.differ.getChanges()); - const entry = changes[0]; - // Typing is represented by only a single change. - if (changes.length != 1 || entry.type !== 'insert' || entry.name != '$text' || entry.length != 1) { - return; - } - const focus = selection.focus; - const block = focus.parent; - const { text, range } = getTextAfterCode(model.createRange(model.createPositionAt(block, 0), focus), model); - const testOutput = testCallback(text); - const rangesToFormat = testOutputToRanges(range.start, testOutput.format, model); - const rangesToRemove = testOutputToRanges(range.start, testOutput.remove, model); - if (!(rangesToFormat.length && rangesToRemove.length)) { - return; - } - // Use enqueueChange to create new batch to separate typing batch from the auto-format changes. - model.enqueueChange(writer => { - // Apply format. - const hasChanged = formatCallback(writer, rangesToFormat); - // Strict check on `false` to have backward compatibility (when callbacks were returning `undefined`). - if (hasChanged === false) { - return; - } - // Remove delimiters - use reversed order to not mix the offsets while removing. - for (const range of rangesToRemove.reverse()) { - writer.remove(range); - } - model.enqueueChange(() => { - const deletePlugin = editor.plugins.get('Delete'); - deletePlugin.requestUndoOnBackspace(); - }); - }); - }); -} -/** - * Converts output of the test function provided to the inlineAutoformatEditing and converts it to the model ranges - * inside provided block. - */ -function testOutputToRanges(start, arrays, model) { - return arrays - .filter(array => (array[0] !== undefined && array[1] !== undefined)) - .map(array => { - return model.createRange(start.getShiftedBy(array[0]), start.getShiftedBy(array[1])); - }); -} -/** - * Returns the last text line after the last code element from the given range. - * It is similar to {@link module:typing/utils/getlasttextline.getLastTextLine `getLastTextLine()`}, - * but it ignores any text before the last `code`. - */ -function getTextAfterCode(range, model) { - let start = range.start; - const text = Array.from(range.getItems()).reduce((rangeText, node) => { - // Trim text to a last occurrence of an inline element and update range start. - if (!(node.is('$text') || node.is('$textProxy')) || node.getAttribute('code')) { - start = model.createPositionAfter(node); - return ''; - } - return rangeText + node.data; - }, ''); - return { text, range: model.createRange(start, range.end) }; -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js": -/*!*******************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js ***! - \*******************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ AttributeCommand) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/attributecommand - */ - -/** - * An extension of the base {@link module:core/command~Command} class, which provides utilities for a command - * that toggles a single attribute on a text or an element. - * - * `AttributeCommand` uses {@link module:engine/model/document~Document#selection} - * to decide which nodes (if any) should be changed, and applies or removes the attribute from them. - * - * The command checks the {@link module:engine/model/model~Model#schema} to decide if it can be enabled - * for the current selection and to which nodes the attribute can be applied. - */ -class AttributeCommand extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Command { - /** - * @param attributeKey Attribute that will be set by the command. - */ - constructor(editor, attributeKey) { - super(editor); - this.attributeKey = attributeKey; - } - /** - * Updates the command's {@link #value} and {@link #isEnabled} based on the current selection. - */ - refresh() { - const model = this.editor.model; - const doc = model.document; - this.value = this._getValueFromFirstAllowedNode(); - this.isEnabled = model.schema.checkAttributeInSelection(doc.selection, this.attributeKey); - } - /** - * Executes the command — applies the attribute to the selection or removes it from the selection. - * - * If the command is active (`value == true`), it will remove attributes. Otherwise, it will set attributes. - * - * The execution result differs, depending on the {@link module:engine/model/document~Document#selection}: - * - * * If the selection is on a range, the command applies the attribute to all nodes in that range - * (if they are allowed to have this attribute by the {@link module:engine/model/schema~Schema schema}). - * * If the selection is collapsed in a non-empty node, the command applies the attribute to the - * {@link module:engine/model/document~Document#selection} itself (note that typed characters copy attributes from the selection). - * * If the selection is collapsed in an empty node, the command applies the attribute to the parent node of the selection (note - * that the selection inherits all attributes from a node if it is in an empty node). - * - * @fires execute - * @param options Command options. - * @param options.forceValue If set, it will force the command behavior. If `true`, - * the command will apply the attribute, otherwise the command will remove the attribute. - * If not set, the command will look for its current value to decide what it should do. - */ - execute(options = {}) { - const model = this.editor.model; - const doc = model.document; - const selection = doc.selection; - const value = (options.forceValue === undefined) ? !this.value : options.forceValue; - model.change(writer => { - if (selection.isCollapsed) { - if (value) { - writer.setSelectionAttribute(this.attributeKey, true); - } - else { - writer.removeSelectionAttribute(this.attributeKey); - } - } - else { - const ranges = model.schema.getValidRanges(selection.getRanges(), this.attributeKey); - for (const range of ranges) { - if (value) { - writer.setAttribute(this.attributeKey, value, range); - } - else { - writer.removeAttribute(this.attributeKey, range); - } - } - } - }); - } - /** - * Checks the attribute value of the first node in the selection that allows the attribute. - * For the collapsed selection returns the selection attribute. - * - * @returns The attribute value. - */ - _getValueFromFirstAllowedNode() { - const model = this.editor.model; - const schema = model.schema; - const selection = model.document.selection; - if (selection.isCollapsed) { - return selection.hasAttribute(this.attributeKey); - } - for (const range of selection.getRanges()) { - for (const item of range.getItems()) { - if (schema.checkAttribute(item, this.attributeKey)) { - return item.hasAttribute(this.attributeKey); - } - } - } - return false; - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/augmentation.js": -/*!***************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/augmentation.js ***! - \***************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ - - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold.js": -/*!*******************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold.js ***! - \*******************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Bold) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var _bold_boldediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./bold/boldediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldediting.js"); -/* harmony import */ var _bold_boldui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./bold/boldui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldui.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/bold - */ - - - -/** - * The bold feature. - * - * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide - * and the {@glink api/basic-styles package page}. - * - * This is a "glue" plugin which loads the {@link module:basic-styles/bold/boldediting~BoldEditing bold editing feature} - * and {@link module:basic-styles/bold/boldui~BoldUI bold UI feature}. - */ -class Bold extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get requires() { - return [_bold_boldediting__WEBPACK_IMPORTED_MODULE_1__["default"], _bold_boldui__WEBPACK_IMPORTED_MODULE_2__["default"]]; - } - /** - * @inheritDoc - */ - static get pluginName() { - return 'Bold'; - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldediting.js": -/*!*******************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldediting.js ***! - \*******************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ BoldEditing) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/bold/boldediting - */ - - -const BOLD = 'bold'; -/** - * The bold editing feature. - * - * It registers the `'bold'` command and introduces the `bold` attribute in the model which renders to the view - * as a `` element. - */ -class BoldEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'BoldEditing'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - // Allow bold attribute on text nodes. - editor.model.schema.extend('$text', { allowAttributes: BOLD }); - editor.model.schema.setAttributeProperties(BOLD, { - isFormatting: true, - copyOnEnter: true - }); - // Build converter from model to view for data and editing pipelines. - editor.conversion.attributeToElement({ - model: BOLD, - view: 'strong', - upcastAlso: [ - 'b', - viewElement => { - const fontWeight = viewElement.getStyle('font-weight'); - if (!fontWeight) { - return null; - } - // Value of the `font-weight` attribute can be defined as a string or a number. - if (fontWeight == 'bold' || Number(fontWeight) >= 600) { - return { - name: true, - styles: ['font-weight'] - }; - } - return null; - } - ] - }); - // Create bold command. - editor.commands.add(BOLD, new _attributecommand__WEBPACK_IMPORTED_MODULE_1__["default"](editor, BOLD)); - // Set the Ctrl+B keystroke. - editor.keystrokes.set('CTRL+B', BOLD); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldui.js": -/*!**************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldui.js ***! - \**************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ BoldUI) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/bold/boldui - */ - - -const BOLD = 'bold'; -/** - * The bold UI feature. It introduces the Bold button. - */ -class BoldUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'BoldUI'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const t = editor.t; - // Add bold button to feature components. - editor.ui.componentFactory.add(BOLD, locale => { - const command = editor.commands.get(BOLD); - const view = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__.ButtonView(locale); - view.set({ - label: t('Bold'), - icon: ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.icons.bold, - keystroke: 'CTRL+B', - tooltip: true, - isToggleable: true - }); - view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled'); - // Execute command. - this.listenTo(view, 'execute', () => { - editor.execute(BOLD); - editor.editing.view.focus(); - }); - return view; - }); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/code.js": -/*!*******************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/code.js ***! - \*******************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Code) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var _code_codeediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./code/codeediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/code/codeediting.js"); -/* harmony import */ var _code_codeui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./code/codeui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/code/codeui.js"); -/* harmony import */ var _theme_code_css__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../theme/code.css */ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/code.css"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/code - */ - - - - -/** - * The code feature. - * - * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide - * and the {@glink api/basic-styles package page}. - * - * This is a "glue" plugin which loads the {@link module:basic-styles/code/codeediting~CodeEditing code editing feature} - * and {@link module:basic-styles/code/codeui~CodeUI code UI feature}. - */ -class Code extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get requires() { - return [_code_codeediting__WEBPACK_IMPORTED_MODULE_1__["default"], _code_codeui__WEBPACK_IMPORTED_MODULE_2__["default"]]; - } - /** - * @inheritDoc - */ - static get pluginName() { - return 'Code'; - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/code/codeediting.js": -/*!*******************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/code/codeediting.js ***! - \*******************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ CodeEditing) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var ckeditor5_src_typing__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/typing */ "./node_modules/ckeditor5/src/typing.js"); -/* harmony import */ var _attributecommand__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/code/codeediting - */ - - - -const CODE = 'code'; -const HIGHLIGHT_CLASS = 'ck-code_selected'; -/** - * The code editing feature. - * - * It registers the `'code'` command and introduces the `code` attribute in the model which renders to the view - * as a `` element. - */ -class CodeEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'CodeEditing'; - } - /** - * @inheritDoc - */ - static get requires() { - return [ckeditor5_src_typing__WEBPACK_IMPORTED_MODULE_1__.TwoStepCaretMovement]; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - // Allow code attribute on text nodes. - editor.model.schema.extend('$text', { allowAttributes: CODE }); - editor.model.schema.setAttributeProperties(CODE, { - isFormatting: true, - copyOnEnter: false - }); - editor.conversion.attributeToElement({ - model: CODE, - view: 'code', - upcastAlso: { - styles: { - 'word-wrap': 'break-word' - } - } - }); - // Create code command. - editor.commands.add(CODE, new _attributecommand__WEBPACK_IMPORTED_MODULE_2__["default"](editor, CODE)); - // Enable two-step caret movement for `code` attribute. - editor.plugins.get(ckeditor5_src_typing__WEBPACK_IMPORTED_MODULE_1__.TwoStepCaretMovement).registerAttribute(CODE); - // Setup highlight over selected element. - (0,ckeditor5_src_typing__WEBPACK_IMPORTED_MODULE_1__.inlineHighlight)(editor, CODE, 'code', HIGHLIGHT_CLASS); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/code/codeui.js": -/*!**************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/code/codeui.js ***! - \**************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ CodeUI) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); -/* harmony import */ var _theme_icons_code_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../theme/icons/code.svg */ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/code.svg"); -/* harmony import */ var _theme_code_css__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../theme/code.css */ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/code.css"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/code/codeui - */ - - - - -const CODE = 'code'; -/** - * The code UI feature. It introduces the Code button. - */ -class CodeUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'CodeUI'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const t = editor.t; - // Add code button to feature components. - editor.ui.componentFactory.add(CODE, locale => { - const command = editor.commands.get(CODE); - const view = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__.ButtonView(locale); - view.set({ - label: t('Code'), - icon: _theme_icons_code_svg__WEBPACK_IMPORTED_MODULE_2__["default"], - tooltip: true, - isToggleable: true - }); - view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled'); - // Execute command. - this.listenTo(view, 'execute', () => { - editor.execute(CODE); - editor.editing.view.focus(); - }); - return view; - }); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/index.js": -/*!********************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/index.js ***! - \********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Bold: () => (/* reexport safe */ _bold__WEBPACK_IMPORTED_MODULE_0__["default"]), -/* harmony export */ BoldEditing: () => (/* reexport safe */ _bold_boldediting__WEBPACK_IMPORTED_MODULE_1__["default"]), -/* harmony export */ BoldUI: () => (/* reexport safe */ _bold_boldui__WEBPACK_IMPORTED_MODULE_2__["default"]), -/* harmony export */ Code: () => (/* reexport safe */ _code__WEBPACK_IMPORTED_MODULE_3__["default"]), -/* harmony export */ CodeEditing: () => (/* reexport safe */ _code_codeediting__WEBPACK_IMPORTED_MODULE_4__["default"]), -/* harmony export */ CodeUI: () => (/* reexport safe */ _code_codeui__WEBPACK_IMPORTED_MODULE_5__["default"]), -/* harmony export */ Italic: () => (/* reexport safe */ _italic__WEBPACK_IMPORTED_MODULE_6__["default"]), -/* harmony export */ ItalicEditing: () => (/* reexport safe */ _italic_italicediting__WEBPACK_IMPORTED_MODULE_7__["default"]), -/* harmony export */ ItalicUI: () => (/* reexport safe */ _italic_italicui__WEBPACK_IMPORTED_MODULE_8__["default"]), -/* harmony export */ Strikethrough: () => (/* reexport safe */ _strikethrough__WEBPACK_IMPORTED_MODULE_9__["default"]), -/* harmony export */ StrikethroughEditing: () => (/* reexport safe */ _strikethrough_strikethroughediting__WEBPACK_IMPORTED_MODULE_10__["default"]), -/* harmony export */ StrikethroughUI: () => (/* reexport safe */ _strikethrough_strikethroughui__WEBPACK_IMPORTED_MODULE_11__["default"]), -/* harmony export */ Subscript: () => (/* reexport safe */ _subscript__WEBPACK_IMPORTED_MODULE_12__["default"]), -/* harmony export */ SubscriptEditing: () => (/* reexport safe */ _subscript_subscriptediting__WEBPACK_IMPORTED_MODULE_13__["default"]), -/* harmony export */ SubscriptUI: () => (/* reexport safe */ _subscript_subscriptui__WEBPACK_IMPORTED_MODULE_14__["default"]), -/* harmony export */ Superscript: () => (/* reexport safe */ _superscript__WEBPACK_IMPORTED_MODULE_15__["default"]), -/* harmony export */ SuperscriptEditing: () => (/* reexport safe */ _superscript_superscriptediting__WEBPACK_IMPORTED_MODULE_16__["default"]), -/* harmony export */ SuperscriptUI: () => (/* reexport safe */ _superscript_superscriptui__WEBPACK_IMPORTED_MODULE_17__["default"]), -/* harmony export */ Underline: () => (/* reexport safe */ _underline__WEBPACK_IMPORTED_MODULE_18__["default"]), -/* harmony export */ UnderlineEditing: () => (/* reexport safe */ _underline_underlineediting__WEBPACK_IMPORTED_MODULE_19__["default"]), -/* harmony export */ UnderlineUI: () => (/* reexport safe */ _underline_underlineui__WEBPACK_IMPORTED_MODULE_20__["default"]) -/* harmony export */ }); -/* harmony import */ var _bold__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./bold */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold.js"); -/* harmony import */ var _bold_boldediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./bold/boldediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldediting.js"); -/* harmony import */ var _bold_boldui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./bold/boldui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/bold/boldui.js"); -/* harmony import */ var _code__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./code */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/code.js"); -/* harmony import */ var _code_codeediting__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./code/codeediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/code/codeediting.js"); -/* harmony import */ var _code_codeui__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./code/codeui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/code/codeui.js"); -/* harmony import */ var _italic__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./italic */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic.js"); -/* harmony import */ var _italic_italicediting__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./italic/italicediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicediting.js"); -/* harmony import */ var _italic_italicui__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./italic/italicui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicui.js"); -/* harmony import */ var _strikethrough__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./strikethrough */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough.js"); -/* harmony import */ var _strikethrough_strikethroughediting__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./strikethrough/strikethroughediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughediting.js"); -/* harmony import */ var _strikethrough_strikethroughui__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./strikethrough/strikethroughui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughui.js"); -/* harmony import */ var _subscript__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./subscript */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript.js"); -/* harmony import */ var _subscript_subscriptediting__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./subscript/subscriptediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptediting.js"); -/* harmony import */ var _subscript_subscriptui__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./subscript/subscriptui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptui.js"); -/* harmony import */ var _superscript__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./superscript */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript.js"); -/* harmony import */ var _superscript_superscriptediting__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./superscript/superscriptediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptediting.js"); -/* harmony import */ var _superscript_superscriptui__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./superscript/superscriptui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptui.js"); -/* harmony import */ var _underline__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./underline */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline.js"); -/* harmony import */ var _underline_underlineediting__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./underline/underlineediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineediting.js"); -/* harmony import */ var _underline_underlineui__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./underline/underlineui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineui.js"); -/* harmony import */ var _augmentation__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./augmentation */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/augmentation.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles - */ - - - - - - - - - - - - - - - - - - - - - - - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic.js": -/*!*********************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic.js ***! - \*********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Italic) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var _italic_italicediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./italic/italicediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicediting.js"); -/* harmony import */ var _italic_italicui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./italic/italicui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicui.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/italic - */ - - - -/** - * The italic feature. - * - * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide - * and the {@glink api/basic-styles package page}. - * - * This is a "glue" plugin which loads the {@link module:basic-styles/italic/italicediting~ItalicEditing} and - * {@link module:basic-styles/italic/italicui~ItalicUI} plugins. - */ -class Italic extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get requires() { - return [_italic_italicediting__WEBPACK_IMPORTED_MODULE_1__["default"], _italic_italicui__WEBPACK_IMPORTED_MODULE_2__["default"]]; - } - /** - * @inheritDoc - */ - static get pluginName() { - return 'Italic'; - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicediting.js": -/*!***********************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicediting.js ***! - \***********************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ ItalicEditing) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/italic/italicediting - */ - - -const ITALIC = 'italic'; -/** - * The italic editing feature. - * - * It registers the `'italic'` command, the Ctrl+I keystroke and introduces the `italic` attribute in the model - * which renders to the view as an `` element. - */ -class ItalicEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'ItalicEditing'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - // Allow italic attribute on text nodes. - editor.model.schema.extend('$text', { allowAttributes: ITALIC }); - editor.model.schema.setAttributeProperties(ITALIC, { - isFormatting: true, - copyOnEnter: true - }); - editor.conversion.attributeToElement({ - model: ITALIC, - view: 'i', - upcastAlso: [ - 'em', - { - styles: { - 'font-style': 'italic' - } - } - ] - }); - // Create italic command. - editor.commands.add(ITALIC, new _attributecommand__WEBPACK_IMPORTED_MODULE_1__["default"](editor, ITALIC)); - // Set the Ctrl+I keystroke. - editor.keystrokes.set('CTRL+I', ITALIC); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicui.js": -/*!******************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/italic/italicui.js ***! - \******************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ ItalicUI) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); -/* harmony import */ var _theme_icons_italic_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../theme/icons/italic.svg */ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/italic.svg"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/italic/italicui - */ - - - -const ITALIC = 'italic'; -/** - * The italic UI feature. It introduces the Italic button. - */ -class ItalicUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'ItalicUI'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const t = editor.t; - // Add bold button to feature components. - editor.ui.componentFactory.add(ITALIC, locale => { - const command = editor.commands.get(ITALIC); - const view = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__.ButtonView(locale); - view.set({ - label: t('Italic'), - icon: _theme_icons_italic_svg__WEBPACK_IMPORTED_MODULE_2__["default"], - keystroke: 'CTRL+I', - tooltip: true, - isToggleable: true - }); - view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled'); - // Execute command. - this.listenTo(view, 'execute', () => { - editor.execute(ITALIC); - editor.editing.view.focus(); - }); - return view; - }); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough.js": -/*!****************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough.js ***! - \****************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Strikethrough) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var _strikethrough_strikethroughediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./strikethrough/strikethroughediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughediting.js"); -/* harmony import */ var _strikethrough_strikethroughui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./strikethrough/strikethroughui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughui.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/strikethrough - */ - - - -/** - * The strikethrough feature. - * - * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide - * and the {@glink api/basic-styles package page}. - * - * This is a "glue" plugin which loads the {@link module:basic-styles/strikethrough/strikethroughediting~StrikethroughEditing} and - * {@link module:basic-styles/strikethrough/strikethroughui~StrikethroughUI} plugins. - */ -class Strikethrough extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get requires() { - return [_strikethrough_strikethroughediting__WEBPACK_IMPORTED_MODULE_1__["default"], _strikethrough_strikethroughui__WEBPACK_IMPORTED_MODULE_2__["default"]]; - } - /** - * @inheritDoc - */ - static get pluginName() { - return 'Strikethrough'; - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughediting.js": -/*!*************************************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughediting.js ***! - \*************************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ StrikethroughEditing) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/strikethrough/strikethroughediting - */ - - -const STRIKETHROUGH = 'strikethrough'; -/** - * The strikethrough editing feature. - * - * It registers the `'strikethrough'` command, the Ctrl+Shift+X keystroke and introduces the - * `strikethroughsthrough` attribute in the model which renders to the view - * as a `` element. - */ -class StrikethroughEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'StrikethroughEditing'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - // Allow strikethrough attribute on text nodes. - editor.model.schema.extend('$text', { allowAttributes: STRIKETHROUGH }); - editor.model.schema.setAttributeProperties(STRIKETHROUGH, { - isFormatting: true, - copyOnEnter: true - }); - editor.conversion.attributeToElement({ - model: STRIKETHROUGH, - view: 's', - upcastAlso: [ - 'del', - 'strike', - { - styles: { - 'text-decoration': 'line-through' - } - } - ] - }); - // Create strikethrough command. - editor.commands.add(STRIKETHROUGH, new _attributecommand__WEBPACK_IMPORTED_MODULE_1__["default"](editor, STRIKETHROUGH)); - // Set the Ctrl+Shift+X keystroke. - editor.keystrokes.set('CTRL+SHIFT+X', 'strikethrough'); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughui.js": -/*!********************************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/strikethrough/strikethroughui.js ***! - \********************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ StrikethroughUI) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); -/* harmony import */ var _theme_icons_strikethrough_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../theme/icons/strikethrough.svg */ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/strikethrough.svg"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/strikethrough/strikethroughui - */ - - - -const STRIKETHROUGH = 'strikethrough'; -/** - * The strikethrough UI feature. It introduces the Strikethrough button. - */ -class StrikethroughUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'StrikethroughUI'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const t = editor.t; - // Add strikethrough button to feature components. - editor.ui.componentFactory.add(STRIKETHROUGH, locale => { - const command = editor.commands.get(STRIKETHROUGH); - const view = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__.ButtonView(locale); - view.set({ - label: t('Strikethrough'), - icon: _theme_icons_strikethrough_svg__WEBPACK_IMPORTED_MODULE_2__["default"], - keystroke: 'CTRL+SHIFT+X', - tooltip: true, - isToggleable: true - }); - view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled'); - // Execute command. - this.listenTo(view, 'execute', () => { - editor.execute(STRIKETHROUGH); - editor.editing.view.focus(); - }); - return view; - }); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript.js": -/*!************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript.js ***! - \************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Subscript) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var _subscript_subscriptediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./subscript/subscriptediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptediting.js"); -/* harmony import */ var _subscript_subscriptui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./subscript/subscriptui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptui.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/subscript - */ - - - -/** - * The subscript feature. - * - * It loads the {@link module:basic-styles/subscript/subscriptediting~SubscriptEditing} and - * {@link module:basic-styles/subscript/subscriptui~SubscriptUI} plugins. - */ -class Subscript extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get requires() { - return [_subscript_subscriptediting__WEBPACK_IMPORTED_MODULE_1__["default"], _subscript_subscriptui__WEBPACK_IMPORTED_MODULE_2__["default"]]; - } - /** - * @inheritDoc - */ - static get pluginName() { - return 'Subscript'; - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptediting.js": -/*!*****************************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptediting.js ***! - \*****************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ SubscriptEditing) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/subscript/subscriptediting - */ - - -const SUBSCRIPT = 'subscript'; -/** - * The subscript editing feature. - * - * It registers the `sub` command and introduces the `sub` attribute in the model which renders to the view - * as a `` element. - */ -class SubscriptEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'SubscriptEditing'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - // Allow sub attribute on text nodes. - editor.model.schema.extend('$text', { allowAttributes: SUBSCRIPT }); - editor.model.schema.setAttributeProperties(SUBSCRIPT, { - isFormatting: true, - copyOnEnter: true - }); - // Build converter from model to view for data and editing pipelines. - editor.conversion.attributeToElement({ - model: SUBSCRIPT, - view: 'sub', - upcastAlso: [ - { - styles: { - 'vertical-align': 'sub' - } - } - ] - }); - // Create sub command. - editor.commands.add(SUBSCRIPT, new _attributecommand__WEBPACK_IMPORTED_MODULE_1__["default"](editor, SUBSCRIPT)); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptui.js": -/*!************************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/subscript/subscriptui.js ***! - \************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ SubscriptUI) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); -/* harmony import */ var _theme_icons_subscript_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../theme/icons/subscript.svg */ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/subscript.svg"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/subscript/subscriptui - */ - - - -const SUBSCRIPT = 'subscript'; -/** - * The subscript UI feature. It introduces the Subscript button. - */ -class SubscriptUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'SubscriptUI'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const t = editor.t; - // Add subscript button to feature components. - editor.ui.componentFactory.add(SUBSCRIPT, locale => { - const command = editor.commands.get(SUBSCRIPT); - const view = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__.ButtonView(locale); - view.set({ - label: t('Subscript'), - icon: _theme_icons_subscript_svg__WEBPACK_IMPORTED_MODULE_2__["default"], - tooltip: true, - isToggleable: true - }); - view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled'); - // Execute command. - this.listenTo(view, 'execute', () => { - editor.execute(SUBSCRIPT); - editor.editing.view.focus(); - }); - return view; - }); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript.js": -/*!**************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript.js ***! - \**************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Superscript) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var _superscript_superscriptediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./superscript/superscriptediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptediting.js"); -/* harmony import */ var _superscript_superscriptui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./superscript/superscriptui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptui.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/superscript - */ - - - -/** - * The superscript feature. - * - * It loads the {@link module:basic-styles/superscript/superscriptediting~SuperscriptEditing} and - * {@link module:basic-styles/superscript/superscriptui~SuperscriptUI} plugins. - */ -class Superscript extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get requires() { - return [_superscript_superscriptediting__WEBPACK_IMPORTED_MODULE_1__["default"], _superscript_superscriptui__WEBPACK_IMPORTED_MODULE_2__["default"]]; - } - /** - * @inheritDoc - */ - static get pluginName() { - return 'Superscript'; - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptediting.js": -/*!*********************************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptediting.js ***! - \*********************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ SuperscriptEditing) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/superscript/superscriptediting - */ - - -const SUPERSCRIPT = 'superscript'; -/** - * The superscript editing feature. - * - * It registers the `super` command and introduces the `super` attribute in the model which renders to the view - * as a `` element. - */ -class SuperscriptEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'SuperscriptEditing'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - // Allow super attribute on text nodes. - editor.model.schema.extend('$text', { allowAttributes: SUPERSCRIPT }); - editor.model.schema.setAttributeProperties(SUPERSCRIPT, { - isFormatting: true, - copyOnEnter: true - }); - // Build converter from model to view for data and editing pipelines. - editor.conversion.attributeToElement({ - model: SUPERSCRIPT, - view: 'sup', - upcastAlso: [ - { - styles: { - 'vertical-align': 'super' - } - } - ] - }); - // Create super command. - editor.commands.add(SUPERSCRIPT, new _attributecommand__WEBPACK_IMPORTED_MODULE_1__["default"](editor, SUPERSCRIPT)); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptui.js": -/*!****************************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/superscript/superscriptui.js ***! - \****************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ SuperscriptUI) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); -/* harmony import */ var _theme_icons_superscript_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../theme/icons/superscript.svg */ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/superscript.svg"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/superscript/superscriptui - */ - - - -const SUPERSCRIPT = 'superscript'; -/** - * The superscript UI feature. It introduces the Superscript button. - */ -class SuperscriptUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'SuperscriptUI'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const t = editor.t; - // Add superscript button to feature components. - editor.ui.componentFactory.add(SUPERSCRIPT, locale => { - const command = editor.commands.get(SUPERSCRIPT); - const view = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__.ButtonView(locale); - view.set({ - label: t('Superscript'), - icon: _theme_icons_superscript_svg__WEBPACK_IMPORTED_MODULE_2__["default"], - tooltip: true, - isToggleable: true - }); - view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled'); - // Execute command. - this.listenTo(view, 'execute', () => { - editor.execute(SUPERSCRIPT); - editor.editing.view.focus(); - }); - return view; - }); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline.js": -/*!************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline.js ***! - \************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Underline) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var _underline_underlineediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./underline/underlineediting */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineediting.js"); -/* harmony import */ var _underline_underlineui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./underline/underlineui */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineui.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/underline - */ - - - -/** - * The underline feature. - * - * For a detailed overview check the {@glink features/basic-styles Basic styles feature} guide - * and the {@glink api/basic-styles package page}. - * - * This is a "glue" plugin which loads the {@link module:basic-styles/underline/underlineediting~UnderlineEditing} and - * {@link module:basic-styles/underline/underlineui~UnderlineUI} plugins. - */ -class Underline extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get requires() { - return [_underline_underlineediting__WEBPACK_IMPORTED_MODULE_1__["default"], _underline_underlineui__WEBPACK_IMPORTED_MODULE_2__["default"]]; - } - /** - * @inheritDoc - */ - static get pluginName() { - return 'Underline'; - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineediting.js": -/*!*****************************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineediting.js ***! - \*****************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ UnderlineEditing) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var _attributecommand__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../attributecommand */ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/attributecommand.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/underline/underlineediting - */ - - -const UNDERLINE = 'underline'; -/** - * The underline editing feature. - * - * It registers the `'underline'` command, the Ctrl+U keystroke - * and introduces the `underline` attribute in the model which renders to the view as an `` element. - */ -class UnderlineEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'UnderlineEditing'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - // Allow strikethrough attribute on text nodes. - editor.model.schema.extend('$text', { allowAttributes: UNDERLINE }); - editor.model.schema.setAttributeProperties(UNDERLINE, { - isFormatting: true, - copyOnEnter: true - }); - editor.conversion.attributeToElement({ - model: UNDERLINE, - view: 'u', - upcastAlso: { - styles: { - 'text-decoration': 'underline' - } - } - }); - // Create underline command. - editor.commands.add(UNDERLINE, new _attributecommand__WEBPACK_IMPORTED_MODULE_1__["default"](editor, UNDERLINE)); - // Set the Ctrl+U keystroke. - editor.keystrokes.set('CTRL+U', 'underline'); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineui.js": -/*!************************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-basic-styles/src/underline/underlineui.js ***! - \************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ UnderlineUI) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); -/* harmony import */ var _theme_icons_underline_svg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../theme/icons/underline.svg */ "./node_modules/@ckeditor/ckeditor5-basic-styles/theme/icons/underline.svg"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module basic-styles/underline/underlineui - */ - - - -const UNDERLINE = 'underline'; -/** - * The underline UI feature. It introduces the Underline button. - */ -class UnderlineUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'UnderlineUI'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const t = editor.t; - // Add bold button to feature components. - editor.ui.componentFactory.add(UNDERLINE, locale => { - const command = editor.commands.get(UNDERLINE); - const view = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__.ButtonView(locale); - view.set({ - label: t('Underline'), - icon: _theme_icons_underline_svg__WEBPACK_IMPORTED_MODULE_2__["default"], - keystroke: 'CTRL+U', - tooltip: true, - isToggleable: true - }); - view.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled'); - // Execute command. - this.listenTo(view, 'execute', () => { - editor.execute(UNDERLINE); - editor.editing.view.focus(); - }); - return view; - }); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-block-quote/src/augmentation.js": -/*!**************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-block-quote/src/augmentation.js ***! - \**************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ - - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquote.js": -/*!************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquote.js ***! - \************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ BlockQuote) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var _blockquoteediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./blockquoteediting */ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteediting.js"); -/* harmony import */ var _blockquoteui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./blockquoteui */ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteui.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module block-quote/blockquote - */ - - - -/** - * The block quote plugin. - * - * For more information about this feature check the {@glink api/block-quote package page}. - * - * This is a "glue" plugin which loads the {@link module:block-quote/blockquoteediting~BlockQuoteEditing block quote editing feature} - * and {@link module:block-quote/blockquoteui~BlockQuoteUI block quote UI feature}. - * - * @extends module:core/plugin~Plugin - */ -class BlockQuote extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get requires() { - return [_blockquoteediting__WEBPACK_IMPORTED_MODULE_1__["default"], _blockquoteui__WEBPACK_IMPORTED_MODULE_2__["default"]]; - } - /** - * @inheritDoc - */ - static get pluginName() { - return 'BlockQuote'; - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquotecommand.js": -/*!*******************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquotecommand.js ***! - \*******************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ BlockQuoteCommand) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/utils */ "./node_modules/ckeditor5/src/utils.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module block-quote/blockquotecommand - */ - - -/** - * The block quote command plugin. - * - * @extends module:core/command~Command - */ -class BlockQuoteCommand extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Command { - /** - * @inheritDoc - */ - refresh() { - this.value = this._getValue(); - this.isEnabled = this._checkEnabled(); - } - /** - * Executes the command. When the command {@link #value is on}, all top-most block quotes within - * the selection will be removed. If it is off, all selected blocks will be wrapped with - * a block quote. - * - * @fires execute - * @param options Command options. - * @param options.forceValue If set, it will force the command behavior. If `true`, the command will apply a block quote, - * otherwise the command will remove the block quote. If not set, the command will act basing on its current value. - */ - execute(options = {}) { - const model = this.editor.model; - const schema = model.schema; - const selection = model.document.selection; - const blocks = Array.from(selection.getSelectedBlocks()); - const value = (options.forceValue === undefined) ? !this.value : options.forceValue; - model.change(writer => { - if (!value) { - this._removeQuote(writer, blocks.filter(findQuote)); - } - else { - const blocksToQuote = blocks.filter(block => { - // Already quoted blocks needs to be considered while quoting too - // in order to reuse their elements. - return findQuote(block) || checkCanBeQuoted(schema, block); - }); - this._applyQuote(writer, blocksToQuote); - } - }); - } - /** - * Checks the command's {@link #value}. - */ - _getValue() { - const selection = this.editor.model.document.selection; - const firstBlock = (0,ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_1__.first)(selection.getSelectedBlocks()); - // In the current implementation, the block quote must be an immediate parent of a block element. - return !!(firstBlock && findQuote(firstBlock)); - } - /** - * Checks whether the command can be enabled in the current context. - * - * @returns Whether the command should be enabled. - */ - _checkEnabled() { - if (this.value) { - return true; - } - const selection = this.editor.model.document.selection; - const schema = this.editor.model.schema; - const firstBlock = (0,ckeditor5_src_utils__WEBPACK_IMPORTED_MODULE_1__.first)(selection.getSelectedBlocks()); - if (!firstBlock) { - return false; - } - return checkCanBeQuoted(schema, firstBlock); - } - /** - * Removes the quote from given blocks. - * - * If blocks which are supposed to be "unquoted" are in the middle of a quote, - * start it or end it, then the quote will be split (if needed) and the blocks - * will be moved out of it, so other quoted blocks remained quoted. - */ - _removeQuote(writer, blocks) { - // Unquote all groups of block. Iterate in the reverse order to not break following ranges. - getRangesOfBlockGroups(writer, blocks).reverse().forEach(groupRange => { - if (groupRange.start.isAtStart && groupRange.end.isAtEnd) { - writer.unwrap(groupRange.start.parent); - return; - } - // The group of blocks are at the beginning of an so let's move them left (out of the ). - if (groupRange.start.isAtStart) { - const positionBefore = writer.createPositionBefore(groupRange.start.parent); - writer.move(groupRange, positionBefore); - return; - } - // The blocks are in the middle of an so we need to split the after the last block - // so we move the items there. - if (!groupRange.end.isAtEnd) { - writer.split(groupRange.end); - } - // Now we are sure that groupRange.end.isAtEnd is true, so let's move the blocks right. - const positionAfter = writer.createPositionAfter(groupRange.end.parent); - writer.move(groupRange, positionAfter); - }); - } - /** - * Applies the quote to given blocks. - */ - _applyQuote(writer, blocks) { - const quotesToMerge = []; - // Quote all groups of block. Iterate in the reverse order to not break following ranges. - getRangesOfBlockGroups(writer, blocks).reverse().forEach(groupRange => { - let quote = findQuote(groupRange.start); - if (!quote) { - quote = writer.createElement('blockQuote'); - writer.wrap(groupRange, quote); - } - quotesToMerge.push(quote); - }); - // Merge subsequent elements. Reverse the order again because this time we want to go through - // the elements in the source order (due to how merge works – it moves the right element's content - // to the first element and removes the right one. Since we may need to merge a couple of subsequent `` elements - // we want to keep the reference to the first (furthest left) one. - quotesToMerge.reverse().reduce((currentQuote, nextQuote) => { - if (currentQuote.nextSibling == nextQuote) { - writer.merge(writer.createPositionAfter(currentQuote)); - return currentQuote; - } - return nextQuote; - }); - } -} -function findQuote(elementOrPosition) { - return elementOrPosition.parent.name == 'blockQuote' ? elementOrPosition.parent : null; -} -/** - * Returns a minimal array of ranges containing groups of subsequent blocks. - * - * content: abcdefgh - * blocks: [ a, b, d, f, g, h ] - * output ranges: [ab]c[d]e[fgh] - */ -function getRangesOfBlockGroups(writer, blocks) { - let startPosition; - let i = 0; - const ranges = []; - while (i < blocks.length) { - const block = blocks[i]; - const nextBlock = blocks[i + 1]; - if (!startPosition) { - startPosition = writer.createPositionBefore(block); - } - if (!nextBlock || block.nextSibling != nextBlock) { - ranges.push(writer.createRange(startPosition, writer.createPositionAfter(block))); - startPosition = null; - } - i++; - } - return ranges; -} -/** - * Checks whether can wrap the block. - */ -function checkCanBeQuoted(schema, block) { - // TMP will be replaced with schema.checkWrap(). - const isBQAllowed = schema.checkChild(block.parent, 'blockQuote'); - const isBlockAllowedInBQ = schema.checkChild(['$root', 'blockQuote'], block); - return isBQAllowed && isBlockAllowedInBQ; -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteediting.js": -/*!*******************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteediting.js ***! - \*******************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ BlockQuoteEditing) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var ckeditor5_src_enter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/enter */ "./node_modules/ckeditor5/src/enter.js"); -/* harmony import */ var ckeditor5_src_typing__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ckeditor5/src/typing */ "./node_modules/ckeditor5/src/typing.js"); -/* harmony import */ var _blockquotecommand__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./blockquotecommand */ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquotecommand.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module block-quote/blockquoteediting - */ - - - - -/** - * The block quote editing. - * - * Introduces the `'blockQuote'` command and the `'blockQuote'` model element. - * - * @extends module:core/plugin~Plugin - */ -class BlockQuoteEditing extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'BlockQuoteEditing'; - } - /** - * @inheritDoc - */ - static get requires() { - return [ckeditor5_src_enter__WEBPACK_IMPORTED_MODULE_1__.Enter, ckeditor5_src_typing__WEBPACK_IMPORTED_MODULE_2__.Delete]; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const schema = editor.model.schema; - editor.commands.add('blockQuote', new _blockquotecommand__WEBPACK_IMPORTED_MODULE_3__["default"](editor)); - schema.register('blockQuote', { - inheritAllFrom: '$container' - }); - editor.conversion.elementToElement({ model: 'blockQuote', view: 'blockquote' }); - // Postfixer which cleans incorrect model states connected with block quotes. - editor.model.document.registerPostFixer(writer => { - const changes = editor.model.document.differ.getChanges(); - for (const entry of changes) { - if (entry.type == 'insert') { - const element = entry.position.nodeAfter; - if (!element) { - // We are inside a text node. - continue; - } - if (element.is('element', 'blockQuote') && element.isEmpty) { - // Added an empty blockQuote - remove it. - writer.remove(element); - return true; - } - else if (element.is('element', 'blockQuote') && !schema.checkChild(entry.position, element)) { - // Added a blockQuote in incorrect place. Unwrap it so the content inside is not lost. - writer.unwrap(element); - return true; - } - else if (element.is('element')) { - // Just added an element. Check that all children meet the scheme rules. - const range = writer.createRangeIn(element); - for (const child of range.getItems()) { - if (child.is('element', 'blockQuote') && - !schema.checkChild(writer.createPositionBefore(child), child)) { - writer.unwrap(child); - return true; - } - } - } - } - else if (entry.type == 'remove') { - const parent = entry.position.parent; - if (parent.is('element', 'blockQuote') && parent.isEmpty) { - // Something got removed and now blockQuote is empty. Remove the blockQuote as well. - writer.remove(parent); - return true; - } - } - } - return false; - }); - const viewDocument = this.editor.editing.view.document; - const selection = editor.model.document.selection; - const blockQuoteCommand = editor.commands.get('blockQuote'); - // Overwrite default Enter key behavior. - // If Enter key is pressed with selection collapsed in empty block inside a quote, break the quote. - this.listenTo(viewDocument, 'enter', (evt, data) => { - if (!selection.isCollapsed || !blockQuoteCommand.value) { - return; - } - const positionParent = selection.getLastPosition().parent; - if (positionParent.isEmpty) { - editor.execute('blockQuote'); - editor.editing.view.scrollToTheSelection(); - data.preventDefault(); - evt.stop(); - } - }, { context: 'blockquote' }); - // Overwrite default Backspace key behavior. - // If Backspace key is pressed with selection collapsed in first empty block inside a quote, break the quote. - this.listenTo(viewDocument, 'delete', (evt, data) => { - if (data.direction != 'backward' || !selection.isCollapsed || !blockQuoteCommand.value) { - return; - } - const positionParent = selection.getLastPosition().parent; - if (positionParent.isEmpty && !positionParent.previousSibling) { - editor.execute('blockQuote'); - editor.editing.view.scrollToTheSelection(); - data.preventDefault(); - evt.stop(); - } - }, { context: 'blockquote' }); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteui.js": -/*!**************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteui.js ***! - \**************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ BlockQuoteUI) -/* harmony export */ }); -/* harmony import */ var ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ckeditor5/src/core */ "./node_modules/ckeditor5/src/core.js"); -/* harmony import */ var ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ckeditor5/src/ui */ "./node_modules/ckeditor5/src/ui.js"); -/* harmony import */ var _theme_blockquote_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../theme/blockquote.css */ "./node_modules/@ckeditor/ckeditor5-block-quote/theme/blockquote.css"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module block-quote/blockquoteui - */ - - - -/** - * The block quote UI plugin. - * - * It introduces the `'blockQuote'` button. - * - * @extends module:core/plugin~Plugin - */ -class BlockQuoteUI extends ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'BlockQuoteUI'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const t = editor.t; - editor.ui.componentFactory.add('blockQuote', locale => { - const command = editor.commands.get('blockQuote'); - const buttonView = new ckeditor5_src_ui__WEBPACK_IMPORTED_MODULE_1__.ButtonView(locale); - buttonView.set({ - label: t('Block quote'), - icon: ckeditor5_src_core__WEBPACK_IMPORTED_MODULE_0__.icons.quote, - tooltip: true, - isToggleable: true - }); - // Bind button model to command. - buttonView.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled'); - // Execute command. - this.listenTo(buttonView, 'execute', () => { - editor.execute('blockQuote'); - editor.editing.view.focus(); - }); - return buttonView; - }); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-block-quote/src/index.js": -/*!*******************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-block-quote/src/index.js ***! - \*******************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ BlockQuote: () => (/* reexport safe */ _blockquote__WEBPACK_IMPORTED_MODULE_0__["default"]), -/* harmony export */ BlockQuoteEditing: () => (/* reexport safe */ _blockquoteediting__WEBPACK_IMPORTED_MODULE_1__["default"]), -/* harmony export */ BlockQuoteUI: () => (/* reexport safe */ _blockquoteui__WEBPACK_IMPORTED_MODULE_2__["default"]) -/* harmony export */ }); -/* harmony import */ var _blockquote__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./blockquote */ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquote.js"); -/* harmony import */ var _blockquoteediting__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./blockquoteediting */ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteediting.js"); -/* harmony import */ var _blockquoteui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./blockquoteui */ "./node_modules/@ckeditor/ckeditor5-block-quote/src/blockquoteui.js"); -/* harmony import */ var _augmentation__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./augmentation */ "./node_modules/@ckeditor/ckeditor5-block-quote/src/augmentation.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module block-quote - */ - - - - - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/augmentation.js": -/*!************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/augmentation.js ***! - \************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ - - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboard.js": -/*!*********************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboard.js ***! - \*********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Clipboard) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core */ "./node_modules/@ckeditor/ckeditor5-core/src/index.js"); -/* harmony import */ var _clipboardpipeline__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./clipboardpipeline */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.js"); -/* harmony import */ var _dragdrop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./dragdrop */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdrop.js"); -/* harmony import */ var _pasteplaintext__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./pasteplaintext */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/pasteplaintext.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module clipboard/clipboard - */ - - - - -/** - * The clipboard feature. - * - * Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide. - * - * This is a "glue" plugin which loads the following plugins: - * * {@link module:clipboard/clipboardpipeline~ClipboardPipeline} - * * {@link module:clipboard/dragdrop~DragDrop} - * * {@link module:clipboard/pasteplaintext~PastePlainText} - */ -class Clipboard extends _ckeditor_ckeditor5_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'Clipboard'; - } - /** - * @inheritDoc - */ - static get requires() { - return [_clipboardpipeline__WEBPACK_IMPORTED_MODULE_1__["default"], _dragdrop__WEBPACK_IMPORTED_MODULE_2__["default"], _pasteplaintext__WEBPACK_IMPORTED_MODULE_3__["default"]]; - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.js": -/*!*****************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.js ***! - \*****************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ ClipboardObserver) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils */ "./node_modules/@ckeditor/ckeditor5-utils/src/index.js"); -/* harmony import */ var _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-engine */ "./node_modules/@ckeditor/ckeditor5-engine/src/index.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module clipboard/clipboardobserver - */ - - -/** - * Clipboard events observer. - * - * Fires the following events: - * - * * {@link module:engine/view/document~Document#event:clipboardInput}, - * * {@link module:engine/view/document~Document#event:paste}, - * * {@link module:engine/view/document~Document#event:copy}, - * * {@link module:engine/view/document~Document#event:cut}, - * * {@link module:engine/view/document~Document#event:drop}, - * * {@link module:engine/view/document~Document#event:dragover}, - * * {@link module:engine/view/document~Document#event:dragging}, - * * {@link module:engine/view/document~Document#event:dragstart}, - * * {@link module:engine/view/document~Document#event:dragend}, - * * {@link module:engine/view/document~Document#event:dragenter}, - * * {@link module:engine/view/document~Document#event:dragleave}. - * - * **Note**: This observer is not available by default (ckeditor5-engine does not add it on its own). - * To make it available, it needs to be added to {@link module:engine/view/document~Document} by using - * the {@link module:engine/view/view~View#addObserver `View#addObserver()`} method. Alternatively, you can load the - * {@link module:clipboard/clipboard~Clipboard} plugin which adds this observer automatically (because it uses it). - */ -class ClipboardObserver extends _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.DomEventObserver { - constructor(view) { - super(view); - this.domEventType = [ - 'paste', 'copy', 'cut', 'drop', 'dragover', 'dragstart', 'dragend', 'dragenter', 'dragleave' - ]; - const viewDocument = this.document; - this.listenTo(viewDocument, 'paste', handleInput('clipboardInput'), { priority: 'low' }); - this.listenTo(viewDocument, 'drop', handleInput('clipboardInput'), { priority: 'low' }); - this.listenTo(viewDocument, 'dragover', handleInput('dragging'), { priority: 'low' }); - function handleInput(type) { - return (evt, data) => { - data.preventDefault(); - const targetRanges = data.dropRange ? [data.dropRange] : null; - const eventInfo = new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.EventInfo(viewDocument, type); - viewDocument.fire(eventInfo, { - dataTransfer: data.dataTransfer, - method: evt.name, - targetRanges, - target: data.target, - domEvent: data.domEvent - }); - // If CKEditor handled the input, do not bubble the original event any further. - // This helps external integrations recognize that fact and act accordingly. - // https://github.com/ckeditor/ckeditor5-upload/issues/92 - if (eventInfo.stop.called) { - data.stopPropagation(); - } - }; - } - } - onDomEvent(domEvent) { - const nativeDataTransfer = 'clipboardData' in domEvent ? domEvent.clipboardData : domEvent.dataTransfer; - const cacheFiles = domEvent.type == 'drop' || domEvent.type == 'paste'; - const evtData = { - dataTransfer: new _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.DataTransfer(nativeDataTransfer, { cacheFiles }) - }; - if (domEvent.type == 'drop' || domEvent.type == 'dragover') { - evtData.dropRange = getDropViewRange(this.view, domEvent); - } - this.fire(domEvent.type, domEvent, evtData); - } -} -function getDropViewRange(view, domEvent) { - const domDoc = domEvent.target.ownerDocument; - const x = domEvent.clientX; - const y = domEvent.clientY; - let domRange; - // Webkit & Blink. - if (domDoc.caretRangeFromPoint && domDoc.caretRangeFromPoint(x, y)) { - domRange = domDoc.caretRangeFromPoint(x, y); - } - // FF. - else if (domEvent.rangeParent) { - domRange = domDoc.createRange(); - domRange.setStart(domEvent.rangeParent, domEvent.rangeOffset); - domRange.collapse(true); - } - if (domRange) { - return view.domConverter.domRangeToView(domRange); - } - return null; -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.js": -/*!*****************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.js ***! - \*****************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ ClipboardPipeline) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core */ "./node_modules/@ckeditor/ckeditor5-core/src/index.js"); -/* harmony import */ var _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils */ "./node_modules/@ckeditor/ckeditor5-utils/src/index.js"); -/* harmony import */ var _clipboardobserver__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./clipboardobserver */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.js"); -/* harmony import */ var _utils_plaintexttohtml__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils/plaintexttohtml */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/plaintexttohtml.js"); -/* harmony import */ var _utils_normalizeclipboarddata__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./utils/normalizeclipboarddata */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/normalizeclipboarddata.js"); -/* harmony import */ var _utils_viewtoplaintext__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils/viewtoplaintext */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/viewtoplaintext.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module clipboard/clipboardpipeline - */ - - - - - - -// Input pipeline events overview: -// -// ┌──────────────────────┐ ┌──────────────────────┐ -// │ view.Document │ │ view.Document │ -// │ paste │ │ drop │ -// └───────────┬──────────┘ └───────────┬──────────┘ -// │ │ -// └────────────────┌────────────────┘ -// │ -// ┌─────────V────────┐ -// │ view.Document │ Retrieves text/html or text/plain from data.dataTransfer -// │ clipboardInput │ and processes it to view.DocumentFragment. -// └─────────┬────────┘ -// │ -// ┌───────────V───────────┐ -// │ ClipboardPipeline │ Converts view.DocumentFragment to model.DocumentFragment. -// │ inputTransformation │ -// └───────────┬───────────┘ -// │ -// ┌──────────V──────────┐ -// │ ClipboardPipeline │ Calls model.insertContent(). -// │ contentInsertion │ -// └─────────────────────┘ -// -// -// Output pipeline events overview: -// -// ┌──────────────────────┐ ┌──────────────────────┐ -// │ view.Document │ │ view.Document │ Retrieves the selected model.DocumentFragment -// │ copy │ │ cut │ and converts it to view.DocumentFragment. -// └───────────┬──────────┘ └───────────┬──────────┘ -// │ │ -// └────────────────┌────────────────┘ -// │ -// ┌─────────V────────┐ -// │ view.Document │ Processes view.DocumentFragment to text/html and text/plain -// │ clipboardOutput │ and stores the results in data.dataTransfer. -// └──────────────────┘ -// -/** - * The clipboard pipeline feature. It is responsible for intercepting the `paste` and `drop` events and - * passing the pasted content through a series of events in order to insert it into the editor's content. - * It also handles the `cut` and `copy` events to fill the native clipboard with the serialized editor's data. - * - * # Input pipeline - * - * The behavior of the default handlers (all at a `low` priority): - * - * ## Event: `paste` or `drop` - * - * 1. Translates the event data. - * 2. Fires the {@link module:engine/view/document~Document#event:clipboardInput `view.Document#clipboardInput`} event. - * - * ## Event: `view.Document#clipboardInput` - * - * 1. If the `data.content` event field is already set (by some listener on a higher priority), it takes this content and fires the event - * from the last point. - * 2. Otherwise, it retrieves `text/html` or `text/plain` from `data.dataTransfer`. - * 3. Normalizes the raw data by applying simple filters on string data. - * 4. Processes the raw data to {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`} with the - * {@link module:engine/controller/datacontroller~DataController#htmlProcessor `DataController#htmlProcessor`}. - * 5. Fires the {@link module:clipboard/clipboardpipeline~ClipboardPipeline#event:inputTransformation - * `ClipboardPipeline#inputTransformation`} event with the view document fragment in the `data.content` event field. - * - * ## Event: `ClipboardPipeline#inputTransformation` - * - * 1. Converts {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`} from the `data.content` field to - * {@link module:engine/model/documentfragment~DocumentFragment `model.DocumentFragment`}. - * 2. Fires the {@link module:clipboard/clipboardpipeline~ClipboardPipeline#event:contentInsertion `ClipboardPipeline#contentInsertion`} - * event with the model document fragment in the `data.content` event field. - * **Note**: The `ClipboardPipeline#contentInsertion` event is fired within a model change block to allow other handlers - * to run in the same block without post-fixers called in between (i.e., the selection post-fixer). - * - * ## Event: `ClipboardPipeline#contentInsertion` - * - * 1. Calls {@link module:engine/model/model~Model#insertContent `model.insertContent()`} to insert `data.content` - * at the current selection position. - * - * # Output pipeline - * - * The behavior of the default handlers (all at a `low` priority): - * - * ## Event: `copy`, `cut` or `dragstart` - * - * 1. Retrieves the selected {@link module:engine/model/documentfragment~DocumentFragment `model.DocumentFragment`} by calling - * {@link module:engine/model/model~Model#getSelectedContent `model#getSelectedContent()`}. - * 2. Converts the model document fragment to {@link module:engine/view/documentfragment~DocumentFragment `view.DocumentFragment`}. - * 3. Fires the {@link module:engine/view/document~Document#event:clipboardOutput `view.Document#clipboardOutput`} event - * with the view document fragment in the `data.content` event field. - * - * ## Event: `view.Document#clipboardOutput` - * - * 1. Processes `data.content` to HTML and plain text with the - * {@link module:engine/controller/datacontroller~DataController#htmlProcessor `DataController#htmlProcessor`}. - * 2. Updates the `data.dataTransfer` data for `text/html` and `text/plain` with the processed data. - * 3. For the `cut` method, calls {@link module:engine/model/model~Model#deleteContent `model.deleteContent()`} - * on the current selection. - * - * Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide. - */ -class ClipboardPipeline extends _ckeditor_ckeditor5_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'ClipboardPipeline'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const view = editor.editing.view; - view.addObserver(_clipboardobserver__WEBPACK_IMPORTED_MODULE_2__["default"]); - this._setupPasteDrop(); - this._setupCopyCut(); - } - /** - * The clipboard paste pipeline. - */ - _setupPasteDrop() { - const editor = this.editor; - const model = editor.model; - const view = editor.editing.view; - const viewDocument = view.document; - // Pasting is disabled when selection is in non-editable place. - // Dropping is disabled in drag and drop handler. - this.listenTo(viewDocument, 'clipboardInput', (evt, data) => { - if (data.method == 'paste' && !editor.model.canEditAt(editor.model.document.selection)) { - evt.stop(); - } - }, { priority: 'highest' }); - this.listenTo(viewDocument, 'clipboardInput', (evt, data) => { - const dataTransfer = data.dataTransfer; - let content; - // Some feature could already inject content in the higher priority event handler (i.e., codeBlock). - if (data.content) { - content = data.content; - } - else { - let contentData = ''; - if (dataTransfer.getData('text/html')) { - contentData = (0,_utils_normalizeclipboarddata__WEBPACK_IMPORTED_MODULE_4__["default"])(dataTransfer.getData('text/html')); - } - else if (dataTransfer.getData('text/plain')) { - contentData = (0,_utils_plaintexttohtml__WEBPACK_IMPORTED_MODULE_3__["default"])(dataTransfer.getData('text/plain')); - } - content = this.editor.data.htmlProcessor.toView(contentData); - } - const eventInfo = new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.EventInfo(this, 'inputTransformation'); - this.fire(eventInfo, { - content, - dataTransfer, - targetRanges: data.targetRanges, - method: data.method - }); - // If CKEditor handled the input, do not bubble the original event any further. - // This helps external integrations recognize this fact and act accordingly. - // https://github.com/ckeditor/ckeditor5-upload/issues/92 - if (eventInfo.stop.called) { - evt.stop(); - } - view.scrollToTheSelection(); - }, { priority: 'low' }); - this.listenTo(this, 'inputTransformation', (evt, data) => { - if (data.content.isEmpty) { - return; - } - const dataController = this.editor.data; - // Convert the pasted content into a model document fragment. - // The conversion is contextual, but in this case an "all allowed" context is needed - // and for that we use the $clipboardHolder item. - const modelFragment = dataController.toModel(data.content, '$clipboardHolder'); - if (modelFragment.childCount == 0) { - return; - } - evt.stop(); - // Fire content insertion event in a single change block to allow other handlers to run in the same block - // without post-fixers called in between (i.e., the selection post-fixer). - model.change(() => { - this.fire('contentInsertion', { - content: modelFragment, - method: data.method, - dataTransfer: data.dataTransfer, - targetRanges: data.targetRanges - }); - }); - }, { priority: 'low' }); - this.listenTo(this, 'contentInsertion', (evt, data) => { - data.resultRange = model.insertContent(data.content); - }, { priority: 'low' }); - } - /** - * The clipboard copy/cut pipeline. - */ - _setupCopyCut() { - const editor = this.editor; - const modelDocument = editor.model.document; - const view = editor.editing.view; - const viewDocument = view.document; - const onCopyCut = (evt, data) => { - const dataTransfer = data.dataTransfer; - data.preventDefault(); - const content = editor.data.toView(editor.model.getSelectedContent(modelDocument.selection)); - viewDocument.fire('clipboardOutput', { - dataTransfer, - content, - method: evt.name - }); - }; - this.listenTo(viewDocument, 'copy', onCopyCut, { priority: 'low' }); - this.listenTo(viewDocument, 'cut', (evt, data) => { - // Cutting is disabled when selection is in non-editable place. - // See: https://github.com/ckeditor/ckeditor5-clipboard/issues/26. - if (!editor.model.canEditAt(editor.model.document.selection)) { - data.preventDefault(); - } - else { - onCopyCut(evt, data); - } - }, { priority: 'low' }); - this.listenTo(viewDocument, 'clipboardOutput', (evt, data) => { - if (!data.content.isEmpty) { - data.dataTransfer.setData('text/html', this.editor.data.htmlProcessor.toData(data.content)); - data.dataTransfer.setData('text/plain', (0,_utils_viewtoplaintext__WEBPACK_IMPORTED_MODULE_5__["default"])(data.content)); - } - if (data.method == 'cut') { - editor.model.deleteContent(modelDocument.selection); - } - }, { priority: 'low' }); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdrop.js": -/*!********************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdrop.js ***! - \********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ DragDrop) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core */ "./node_modules/@ckeditor/ckeditor5-core/src/index.js"); -/* harmony import */ var _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-engine */ "./node_modules/@ckeditor/ckeditor5-engine/src/index.js"); -/* harmony import */ var _ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @ckeditor/ckeditor5-widget */ "./node_modules/@ckeditor/ckeditor5-widget/src/index.js"); -/* harmony import */ var _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils */ "./node_modules/@ckeditor/ckeditor5-utils/src/index.js"); -/* harmony import */ var _clipboardpipeline__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./clipboardpipeline */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.js"); -/* harmony import */ var _clipboardobserver__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./clipboardobserver */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.js"); -/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! lodash-es */ "./node_modules/lodash-es/throttle.js"); -/* harmony import */ var _theme_clipboard_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../theme/clipboard.css */ "./node_modules/@ckeditor/ckeditor5-clipboard/theme/clipboard.css"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module clipboard/dragdrop - */ - - - - - - - - -// Drag and drop events overview: -// -// ┌──────────────────┐ -// │ mousedown │ Sets the draggable attribute. -// └─────────┬────────┘ -// │ -// └─────────────────────┐ -// │ │ -// │ ┌─────────V────────┐ -// │ │ mouseup │ Dragging did not start, removes the draggable attribute. -// │ └──────────────────┘ -// │ -// ┌─────────V────────┐ Retrieves the selected model.DocumentFragment -// │ dragstart │ and converts it to view.DocumentFragment. -// └─────────┬────────┘ -// │ -// ┌─────────V────────┐ Processes view.DocumentFragment to text/html and text/plain -// │ clipboardOutput │ and stores the results in data.dataTransfer. -// └─────────┬────────┘ -// │ -// │ DOM dragover -// ┌────────────┐ -// │ │ -// ┌─────────V────────┐ │ -// │ dragging │ │ Updates the drop target marker. -// └─────────┬────────┘ │ -// │ │ -// ┌─────────────└────────────┘ -// │ │ │ -// │ ┌─────────V────────┐ │ -// │ │ dragleave │ │ Removes the drop target marker. -// │ └─────────┬────────┘ │ -// │ │ │ -// ┌───│─────────────┘ │ -// │ │ │ │ -// │ │ ┌─────────V────────┐ │ -// │ │ │ dragenter │ │ Focuses the editor view. -// │ │ └─────────┬────────┘ │ -// │ │ │ │ -// │ │ └────────────┘ -// │ │ -// │ └─────────────┐ -// │ │ │ -// │ │ ┌─────────V────────┐ -// └───┐ │ drop │ (The default handler of the clipboard pipeline). -// │ └─────────┬────────┘ -// │ │ -// │ ┌─────────V────────┐ Resolves the final data.targetRanges. -// │ │ clipboardInput │ Aborts if dropping on dragged content. -// │ └─────────┬────────┘ -// │ │ -// │ ┌─────────V────────┐ -// │ │ clipboardInput │ (The default handler of the clipboard pipeline). -// │ └─────────┬────────┘ -// │ │ -// │ ┌───────────V───────────┐ -// │ │ inputTransformation │ (The default handler of the clipboard pipeline). -// │ └───────────┬───────────┘ -// │ │ -// │ ┌──────────V──────────┐ -// │ │ contentInsertion │ Updates the document selection to drop range. -// │ └──────────┬──────────┘ -// │ │ -// │ ┌──────────V──────────┐ -// │ │ contentInsertion │ (The default handler of the clipboard pipeline). -// │ └──────────┬──────────┘ -// │ │ -// │ ┌──────────V──────────┐ -// │ │ contentInsertion │ Removes the content from the original range if the insertion was successful. -// │ └──────────┬──────────┘ -// │ │ -// └─────────────┐ -// │ -// ┌─────────V────────┐ -// │ dragend │ Removes the drop marker and cleans the state. -// └──────────────────┘ -// -/** - * The drag and drop feature. It works on top of the {@link module:clipboard/clipboardpipeline~ClipboardPipeline}. - * - * Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide. - */ -class DragDrop extends _ckeditor_ckeditor5_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'DragDrop'; - } - /** - * @inheritDoc - */ - static get requires() { - return [_clipboardpipeline__WEBPACK_IMPORTED_MODULE_4__["default"], _ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.Widget]; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const view = editor.editing.view; - this._draggedRange = null; - this._draggingUid = ''; - this._draggableElement = null; - this._updateDropMarkerThrottled = (0,lodash_es__WEBPACK_IMPORTED_MODULE_7__["default"])(targetRange => this._updateDropMarker(targetRange), 40); - this._removeDropMarkerDelayed = (0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.delay)(() => this._removeDropMarker(), 40); - this._clearDraggableAttributesDelayed = (0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.delay)(() => this._clearDraggableAttributes(), 40); - if (editor.plugins.has('DragDropExperimental')) { - this.forceDisabled('DragDropExperimental'); - return; - } - view.addObserver(_clipboardobserver__WEBPACK_IMPORTED_MODULE_5__["default"]); - view.addObserver(_ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.MouseObserver); - this._setupDragging(); - this._setupContentInsertionIntegration(); - this._setupClipboardInputIntegration(); - this._setupDropMarker(); - this._setupDraggableAttributeHandling(); - this.listenTo(editor, 'change:isReadOnly', (evt, name, isReadOnly) => { - if (isReadOnly) { - this.forceDisabled('readOnlyMode'); - } - else { - this.clearForceDisabled('readOnlyMode'); - } - }); - this.on('change:isEnabled', (evt, name, isEnabled) => { - if (!isEnabled) { - this._finalizeDragging(false); - } - }); - if (_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.env.isAndroid) { - this.forceDisabled('noAndroidSupport'); - } - } - /** - * @inheritDoc - */ - destroy() { - if (this._draggedRange) { - this._draggedRange.detach(); - this._draggedRange = null; - } - this._updateDropMarkerThrottled.cancel(); - this._removeDropMarkerDelayed.cancel(); - this._clearDraggableAttributesDelayed.cancel(); - return super.destroy(); - } - /** - * Drag and drop events handling. - */ - _setupDragging() { - const editor = this.editor; - const model = editor.model; - const modelDocument = model.document; - const view = editor.editing.view; - const viewDocument = view.document; - // The handler for the drag start; it is responsible for setting data transfer object. - this.listenTo(viewDocument, 'dragstart', (evt, data) => { - const selection = modelDocument.selection; - // Don't drag the editable element itself. - if (data.target && data.target.is('editableElement')) { - data.preventDefault(); - return; - } - // TODO we could clone this node somewhere and style it to match editing view but without handles, - // selection outline, WTA buttons, etc. - // data.dataTransfer._native.setDragImage( data.domTarget, 0, 0 ); - // Check if this is dragstart over the widget (but not a nested editable). - const draggableWidget = data.target ? findDraggableWidget(data.target) : null; - if (draggableWidget) { - const modelElement = editor.editing.mapper.toModelElement(draggableWidget); - this._draggedRange = _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.LiveRange.fromRange(model.createRangeOn(modelElement)); - // Disable toolbars so they won't obscure the drop area. - if (editor.plugins.has('WidgetToolbarRepository')) { - const widgetToolbarRepository = editor.plugins.get('WidgetToolbarRepository'); - widgetToolbarRepository.forceDisabled('dragDrop'); - } - } - // If this was not a widget we should check if we need to drag some text content. - else if (!viewDocument.selection.isCollapsed) { - const selectedElement = viewDocument.selection.getSelectedElement(); - if (!selectedElement || !(0,_ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.isWidget)(selectedElement)) { - this._draggedRange = _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.LiveRange.fromRange(selection.getFirstRange()); - } - } - if (!this._draggedRange) { - data.preventDefault(); - return; - } - this._draggingUid = (0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.uid)(); - const canEditAtDraggedRange = this.isEnabled && editor.model.canEditAt(this._draggedRange); - data.dataTransfer.effectAllowed = canEditAtDraggedRange ? 'copyMove' : 'copy'; - data.dataTransfer.setData('application/ckeditor5-dragging-uid', this._draggingUid); - const draggedSelection = model.createSelection(this._draggedRange.toRange()); - const content = editor.data.toView(model.getSelectedContent(draggedSelection)); - viewDocument.fire('clipboardOutput', { - dataTransfer: data.dataTransfer, - content, - method: 'dragstart' - }); - if (!canEditAtDraggedRange) { - this._draggedRange.detach(); - this._draggedRange = null; - this._draggingUid = ''; - } - }, { priority: 'low' }); - // The handler for finalizing drag and drop. It should always be triggered after dragging completes - // even if it was completed in a different application. - // Note: This is not fired if source text node got removed while downcasting a marker. - this.listenTo(viewDocument, 'dragend', (evt, data) => { - this._finalizeDragging(!data.dataTransfer.isCanceled && data.dataTransfer.dropEffect == 'move'); - }, { priority: 'low' }); - // Dragging over the editable. - this.listenTo(viewDocument, 'dragenter', () => { - if (!this.isEnabled) { - return; - } - view.focus(); - }); - // Dragging out of the editable. - this.listenTo(viewDocument, 'dragleave', () => { - // We do not know if the mouse left the editor or just some element in it, so let us wait a few milliseconds - // to check if 'dragover' is not fired. - this._removeDropMarkerDelayed(); - }); - // Handler for moving dragged content over the target area. - this.listenTo(viewDocument, 'dragging', (evt, data) => { - if (!this.isEnabled) { - data.dataTransfer.dropEffect = 'none'; - return; - } - this._removeDropMarkerDelayed.cancel(); - const targetRange = findDropTargetRange(editor, data.targetRanges, data.target); - // Do not drop if target place is not editable. - if (!editor.model.canEditAt(targetRange)) { - data.dataTransfer.dropEffect = 'none'; - return; - } - // If this is content being dragged from another editor, moving out of current editor instance - // is not possible until 'dragend' event case will be fixed. - if (!this._draggedRange) { - data.dataTransfer.dropEffect = 'copy'; - } - // In Firefox it is already set and effect allowed remains the same as originally set. - if (!_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.env.isGecko) { - if (data.dataTransfer.effectAllowed == 'copy') { - data.dataTransfer.dropEffect = 'copy'; - } - else if (['all', 'copyMove'].includes(data.dataTransfer.effectAllowed)) { - data.dataTransfer.dropEffect = 'move'; - } - } - /* istanbul ignore else -- @preserve */ - if (targetRange) { - this._updateDropMarkerThrottled(targetRange); - } - }, { priority: 'low' }); - } - /** - * Integration with the `clipboardInput` event. - */ - _setupClipboardInputIntegration() { - const editor = this.editor; - const view = editor.editing.view; - const viewDocument = view.document; - // Update the event target ranges and abort dropping if dropping over itself. - this.listenTo(viewDocument, 'clipboardInput', (evt, data) => { - if (data.method != 'drop') { - return; - } - const targetRange = findDropTargetRange(editor, data.targetRanges, data.target); - // The dragging markers must be removed after searching for the target range because sometimes - // the target lands on the marker itself. - this._removeDropMarker(); - /* istanbul ignore if -- @preserve */ - if (!targetRange || !editor.model.canEditAt(targetRange)) { - this._finalizeDragging(false); - evt.stop(); - return; - } - // Since we cannot rely on the drag end event, we must check if the local drag range is from the current drag and drop - // or it is from some previous not cleared one. - if (this._draggedRange && this._draggingUid != data.dataTransfer.getData('application/ckeditor5-dragging-uid')) { - this._draggedRange.detach(); - this._draggedRange = null; - this._draggingUid = ''; - } - // Do not do anything if some content was dragged within the same document to the same position. - const isMove = getFinalDropEffect(data.dataTransfer) == 'move'; - if (isMove && this._draggedRange && this._draggedRange.containsRange(targetRange, true)) { - this._finalizeDragging(false); - evt.stop(); - return; - } - // Override the target ranges with the one adjusted to the best one for a drop. - data.targetRanges = [editor.editing.mapper.toViewRange(targetRange)]; - }, { priority: 'high' }); - } - /** - * Integration with the `contentInsertion` event of the clipboard pipeline. - */ - _setupContentInsertionIntegration() { - const clipboardPipeline = this.editor.plugins.get(_clipboardpipeline__WEBPACK_IMPORTED_MODULE_4__["default"]); - clipboardPipeline.on('contentInsertion', (evt, data) => { - if (!this.isEnabled || data.method !== 'drop') { - return; - } - // Update the selection to the target range in the same change block to avoid selection post-fixing - // and to be able to clone text attributes for plain text dropping. - const ranges = data.targetRanges.map(viewRange => this.editor.editing.mapper.toModelRange(viewRange)); - this.editor.model.change(writer => writer.setSelection(ranges)); - }, { priority: 'high' }); - clipboardPipeline.on('contentInsertion', (evt, data) => { - if (!this.isEnabled || data.method !== 'drop') { - return; - } - // Remove dragged range content, remove markers, clean after dragging. - const isMove = getFinalDropEffect(data.dataTransfer) == 'move'; - // Whether any content was inserted (insertion might fail if the schema is disallowing some elements - // (for example an image caption allows only the content of a block but not blocks themselves. - // Some integrations might not return valid range (i.e., table pasting). - const isSuccess = !data.resultRange || !data.resultRange.isCollapsed; - this._finalizeDragging(isSuccess && isMove); - }, { priority: 'lowest' }); - } - /** - * Adds listeners that add the `draggable` attribute to the elements while the mouse button is down so the dragging could start. - */ - _setupDraggableAttributeHandling() { - const editor = this.editor; - const view = editor.editing.view; - const viewDocument = view.document; - // Add the 'draggable' attribute to the widget while pressing the selection handle. - // This is required for widgets to be draggable. In Chrome it will enable dragging text nodes. - this.listenTo(viewDocument, 'mousedown', (evt, data) => { - // The lack of data can be caused by editor tests firing fake mouse events. This should not occur - // in real-life scenarios but this greatly simplifies editor tests that would otherwise fail a lot. - if (_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.env.isAndroid || !data) { - return; - } - this._clearDraggableAttributesDelayed.cancel(); - // Check if this is a mousedown over the widget (but not a nested editable). - let draggableElement = findDraggableWidget(data.target); - // Note: There is a limitation that if more than a widget is selected (a widget and some text) - // and dragging starts on the widget, then only the widget is dragged. - // If this was not a widget then we should check if we need to drag some text content. - // In Chrome set a 'draggable' attribute on closest editable to allow immediate dragging of the selected text range. - // In Firefox this is not needed. In Safari it makes the whole editable draggable (not just textual content). - // Disabled in read-only mode because draggable="true" + contenteditable="false" results - // in not firing selectionchange event ever, which makes the selection stuck in read-only mode. - if (_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.env.isBlink && !draggableElement && !viewDocument.selection.isCollapsed) { - const selectedElement = viewDocument.selection.getSelectedElement(); - if (!selectedElement || !(0,_ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.isWidget)(selectedElement)) { - const editableElement = viewDocument.selection.editableElement; - if (editableElement && !editableElement.isReadOnly) { - draggableElement = editableElement; - } - } - } - if (draggableElement) { - view.change(writer => { - writer.setAttribute('draggable', 'true', draggableElement); - }); - // Keep the reference to the model element in case the view element gets removed while dragging. - this._draggableElement = editor.editing.mapper.toModelElement(draggableElement); - } - }); - // Remove the draggable attribute in case no dragging started (only mousedown + mouseup). - this.listenTo(viewDocument, 'mouseup', () => { - if (!_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.env.isAndroid) { - this._clearDraggableAttributesDelayed(); - } - }); - } - /** - * Removes the `draggable` attribute from the element that was used for dragging. - */ - _clearDraggableAttributes() { - const editing = this.editor.editing; - editing.view.change(writer => { - // Remove 'draggable' attribute. - if (this._draggableElement && this._draggableElement.root.rootName != '$graveyard') { - writer.removeAttribute('draggable', editing.mapper.toViewElement(this._draggableElement)); - } - this._draggableElement = null; - }); - } - /** - * Creates downcast conversion for the drop target marker. - */ - _setupDropMarker() { - const editor = this.editor; - // Drop marker conversion for hovering over widgets. - editor.conversion.for('editingDowncast').markerToHighlight({ - model: 'drop-target', - view: { - classes: ['ck-clipboard-drop-target-range'] - } - }); - // Drop marker conversion for in text drop target. - editor.conversion.for('editingDowncast').markerToElement({ - model: 'drop-target', - view: (data, { writer }) => { - const inText = editor.model.schema.checkChild(data.markerRange.start, '$text'); - if (!inText) { - return; - } - return writer.createUIElement('span', { class: 'ck ck-clipboard-drop-target-position' }, function (domDocument) { - const domElement = this.toDomElement(domDocument); - // Using word joiner to make this marker as high as text and also making text not break on marker. - domElement.append('\u2060', domDocument.createElement('span'), '\u2060'); - return domElement; - }); - } - }); - } - /** - * Updates the drop target marker to the provided range. - * - * @param targetRange The range to set the marker to. - */ - _updateDropMarker(targetRange) { - const editor = this.editor; - const markers = editor.model.markers; - editor.model.change(writer => { - if (markers.has('drop-target')) { - if (!markers.get('drop-target').getRange().isEqual(targetRange)) { - writer.updateMarker('drop-target', { range: targetRange }); - } - } - else { - writer.addMarker('drop-target', { - range: targetRange, - usingOperation: false, - affectsData: false - }); - } - }); - } - /** - * Removes the drop target marker. - */ - _removeDropMarker() { - const model = this.editor.model; - this._removeDropMarkerDelayed.cancel(); - this._updateDropMarkerThrottled.cancel(); - if (model.markers.has('drop-target')) { - model.change(writer => { - writer.removeMarker('drop-target'); - }); - } - } - /** - * Deletes the dragged content from its original range and clears the dragging state. - * - * @param moved Whether the move succeeded. - */ - _finalizeDragging(moved) { - const editor = this.editor; - const model = editor.model; - this._removeDropMarker(); - this._clearDraggableAttributes(); - if (editor.plugins.has('WidgetToolbarRepository')) { - const widgetToolbarRepository = editor.plugins.get('WidgetToolbarRepository'); - widgetToolbarRepository.clearForceDisabled('dragDrop'); - } - this._draggingUid = ''; - if (!this._draggedRange) { - return; - } - // Delete moved content. - if (moved && this.isEnabled) { - model.deleteContent(model.createSelection(this._draggedRange), { doNotAutoparagraph: true }); - } - this._draggedRange.detach(); - this._draggedRange = null; - } -} -/** - * Returns fixed selection range for given position and target element. - */ -function findDropTargetRange(editor, targetViewRanges, targetViewElement) { - const model = editor.model; - const mapper = editor.editing.mapper; - let range = null; - const targetViewPosition = targetViewRanges ? targetViewRanges[0].start : null; - // A UIElement is not a valid drop element, use parent (this could be a drop marker or any other UIElement). - if (targetViewElement.is('uiElement')) { - targetViewElement = targetViewElement.parent; - } - // Quick win if the target is a widget (but not a nested editable). - range = findDropTargetRangeOnWidget(editor, targetViewElement); - if (range) { - return range; - } - // The easiest part is over, now we need to move to the model space. - // Find target model element and position. - const targetModelElement = getClosestMappedModelElement(editor, targetViewElement); - const targetModelPosition = targetViewPosition ? mapper.toModelPosition(targetViewPosition) : null; - // There is no target position while hovering over an empty table cell. - // In Safari, target position can be empty while hovering over a widget (e.g., a page-break). - // Find the drop position inside the element. - if (!targetModelPosition) { - return findDropTargetRangeInElement(editor, targetModelElement); - } - // Check if target position is between blocks and adjust drop position to the next object. - // This is because while hovering over a root element next to a widget the target position can jump in crazy places. - range = findDropTargetRangeBetweenBlocks(editor, targetModelPosition, targetModelElement); - if (range) { - return range; - } - // Try fixing selection position. - // In Firefox, the target position lands before widgets but in other browsers it tends to land after a widget. - range = model.schema.getNearestSelectionRange(targetModelPosition, _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.env.isGecko ? 'forward' : 'backward'); - if (range) { - return range; - } - // There is no valid selection position inside the current limit element so find a closest object ancestor. - // This happens if the model position lands directly in the element itself (view target element was a `
` - // so a nested editable, but view target position was directly in the `
` element). - return findDropTargetRangeOnAncestorObject(editor, targetModelPosition.parent); -} -/** - * Returns fixed selection range for a given position and a target element if it is over the widget but not over its nested editable. - */ -function findDropTargetRangeOnWidget(editor, targetViewElement) { - const model = editor.model; - const mapper = editor.editing.mapper; - // Quick win if the target is a widget. - if ((0,_ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.isWidget)(targetViewElement)) { - return model.createRangeOn(mapper.toModelElement(targetViewElement)); - } - // Check if we are deeper over a widget (but not over a nested editable). - if (!targetViewElement.is('editableElement')) { - // Find a closest ancestor that is either a widget or an editable element... - const ancestor = targetViewElement.findAncestor(node => (0,_ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.isWidget)(node) || node.is('editableElement')); - // ...and if the widget was closer then it is a drop target. - if ((0,_ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.isWidget)(ancestor)) { - return model.createRangeOn(mapper.toModelElement(ancestor)); - } - } - return null; -} -/** - * Returns fixed selection range inside a model element. - */ -function findDropTargetRangeInElement(editor, targetModelElement) { - const model = editor.model; - const schema = model.schema; - const positionAtElementStart = model.createPositionAt(targetModelElement, 0); - return schema.getNearestSelectionRange(positionAtElementStart, 'forward'); -} -/** - * Returns fixed selection range for a given position and a target element if the drop is between blocks. - */ -function findDropTargetRangeBetweenBlocks(editor, targetModelPosition, targetModelElement) { - const model = editor.model; - // Check if target is between blocks. - if (!model.schema.checkChild(targetModelElement, '$block')) { - return null; - } - // Find position between blocks. - const positionAtElementStart = model.createPositionAt(targetModelElement, 0); - // Get the common part of the path (inside the target element and the target position). - const commonPath = targetModelPosition.path.slice(0, positionAtElementStart.path.length); - // Position between the blocks. - const betweenBlocksPosition = model.createPositionFromPath(targetModelPosition.root, commonPath); - const nodeAfter = betweenBlocksPosition.nodeAfter; - // Adjust drop position to the next object. - // This is because while hovering over a root element next to a widget the target position can jump in crazy places. - if (nodeAfter && model.schema.isObject(nodeAfter)) { - return model.createRangeOn(nodeAfter); - } - return null; -} -/** - * Returns a selection range on the ancestor object. - */ -function findDropTargetRangeOnAncestorObject(editor, element) { - const model = editor.model; - let currentElement = element; - while (currentElement) { - if (model.schema.isObject(currentElement)) { - return model.createRangeOn(currentElement); - } - currentElement = currentElement.parent; - } - /* istanbul ignore next -- @preserve */ - return null; -} -/** - * Returns the closest model element for the specified view element. - */ -function getClosestMappedModelElement(editor, element) { - const mapper = editor.editing.mapper; - const view = editor.editing.view; - const targetModelElement = mapper.toModelElement(element); - if (targetModelElement) { - return targetModelElement; - } - // Find mapped ancestor if the target is inside not mapped element (for example inline code element). - const viewPosition = view.createPositionBefore(element); - const viewElement = mapper.findMappedViewAncestor(viewPosition); - return mapper.toModelElement(viewElement); -} -/** - * Returns the drop effect that should be a result of dragging the content. - * This function is handling a quirk when checking the effect in the 'drop' DOM event. - */ -function getFinalDropEffect(dataTransfer) { - if (_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.env.isGecko) { - return dataTransfer.dropEffect; - } - return ['all', 'copyMove'].includes(dataTransfer.effectAllowed) ? 'move' : 'copy'; -} -/** - * Returns a widget element that should be dragged. - */ -function findDraggableWidget(target) { - // This is directly an editable so not a widget for sure. - if (target.is('editableElement')) { - return null; - } - // TODO: Let's have a isWidgetSelectionHandleDomElement() helper in ckeditor5-widget utils. - if (target.hasClass('ck-widget__selection-handle')) { - return target.findAncestor(_ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.isWidget); - } - // Direct hit on a widget. - if ((0,_ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.isWidget)(target)) { - return target; - } - // Find closest ancestor that is either a widget or an editable element... - const ancestor = target.findAncestor(node => (0,_ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.isWidget)(node) || node.is('editableElement')); - // ...and if closer was the widget then enable dragging it. - if ((0,_ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.isWidget)(ancestor)) { - return ancestor; - } - return null; -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdropblocktoolbar.js": -/*!********************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdropblocktoolbar.js ***! - \********************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ DragDropBlockToolbar) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core */ "./node_modules/@ckeditor/ckeditor5-core/src/index.js"); -/* harmony import */ var _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils */ "./node_modules/@ckeditor/ckeditor5-utils/src/index.js"); -/* harmony import */ var _clipboardobserver__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./clipboardobserver */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module clipboard/dragdropblocktoolbar - */ -/* istanbul ignore file -- @preserve */ - - - -/** - * Integration of an experimental block Drag and drop support with the block toolbar. - * - * @internal - */ -class DragDropBlockToolbar extends _ckeditor_ckeditor5_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - constructor() { - super(...arguments); - /** - * Whether current dragging is started by block toolbar button dragging. - */ - this._isBlockDragging = false; - /** - * DOM Emitter. - */ - this._domEmitter = new ((0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.DomEmitterMixin)())(); - } - /** - * @inheritDoc - */ - static get pluginName() { - return 'DragDropBlockToolbar'; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - this.listenTo(editor, 'change:isReadOnly', (evt, name, isReadOnly) => { - if (isReadOnly) { - this.forceDisabled('readOnlyMode'); - this._isBlockDragging = false; - } - else { - this.clearForceDisabled('readOnlyMode'); - } - }); - if (_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.env.isAndroid) { - this.forceDisabled('noAndroidSupport'); - } - if (editor.plugins.has('BlockToolbar')) { - const blockToolbar = editor.plugins.get('BlockToolbar'); - const element = blockToolbar.buttonView.element; - element.setAttribute('draggable', 'true'); - this._domEmitter.listenTo(element, 'dragstart', (evt, data) => this._handleBlockDragStart(data)); - this._domEmitter.listenTo(_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.global.document, 'dragover', (evt, data) => this._handleBlockDragging(data)); - this._domEmitter.listenTo(_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.global.document, 'drop', (evt, data) => this._handleBlockDragging(data)); - this._domEmitter.listenTo(_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.global.document, 'dragend', () => this._handleBlockDragEnd(), { useCapture: true }); - } - } - /** - * @inheritDoc - */ - destroy() { - this._domEmitter.stopListening(); - return super.destroy(); - } - /** - * The `dragstart` event handler. - */ - _handleBlockDragStart(domEvent) { - if (!this.isEnabled) { - return; - } - const model = this.editor.model; - const selection = model.document.selection; - const blocks = Array.from(selection.getSelectedBlocks()); - const draggedRange = model.createRange(model.createPositionBefore(blocks[0]), model.createPositionAfter(blocks[blocks.length - 1])); - model.change(writer => writer.setSelection(draggedRange)); - this._isBlockDragging = true; - this.editor.editing.view.getObserver(_clipboardobserver__WEBPACK_IMPORTED_MODULE_2__["default"]).onDomEvent(domEvent); - } - /** - * The `dragover` and `drop` event handler. - */ - _handleBlockDragging(domEvent) { - if (!this.isEnabled || !this._isBlockDragging) { - return; - } - const clientX = domEvent.clientX + 100; - const clientY = domEvent.clientY; - const target = document.elementFromPoint(clientX, clientY); - if (!target || !target.closest('.ck-editor__editable')) { - return; - } - this.editor.editing.view.getObserver(_clipboardobserver__WEBPACK_IMPORTED_MODULE_2__["default"]).onDomEvent({ - ...domEvent, - type: domEvent.type, - dataTransfer: domEvent.dataTransfer, - target, - clientX, - clientY, - preventDefault: () => domEvent.preventDefault(), - stopPropagation: () => domEvent.stopPropagation() - }); - } - /** - * The `dragend` event handler. - */ - _handleBlockDragEnd() { - this._isBlockDragging = false; - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdropexperimental.js": -/*!********************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdropexperimental.js ***! - \********************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ DragDropExperimental) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core */ "./node_modules/@ckeditor/ckeditor5-core/src/index.js"); -/* harmony import */ var _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-engine */ "./node_modules/@ckeditor/ckeditor5-engine/src/index.js"); -/* harmony import */ var _ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @ckeditor/ckeditor5-widget */ "./node_modules/@ckeditor/ckeditor5-widget/src/index.js"); -/* harmony import */ var _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils */ "./node_modules/@ckeditor/ckeditor5-utils/src/index.js"); -/* harmony import */ var _clipboardpipeline__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./clipboardpipeline */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.js"); -/* harmony import */ var _clipboardobserver__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./clipboardobserver */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.js"); -/* harmony import */ var _dragdroptarget__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./dragdroptarget */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdroptarget.js"); -/* harmony import */ var _theme_clipboard_css__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../theme/clipboard.css */ "./node_modules/@ckeditor/ckeditor5-clipboard/theme/clipboard.css"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module clipboard/dragdropexperimental - */ -/* istanbul ignore file -- @preserve */ - - - - - - - - -// Drag and drop events overview: -// -// ┌──────────────────┐ -// │ mousedown │ Sets the draggable attribute. -// └─────────┬────────┘ -// │ -// └─────────────────────┐ -// │ │ -// │ ┌─────────V────────┐ -// │ │ mouseup │ Dragging did not start, removes the draggable attribute. -// │ └──────────────────┘ -// │ -// ┌─────────V────────┐ Retrieves the selected model.DocumentFragment -// │ dragstart │ and converts it to view.DocumentFragment. -// └─────────┬────────┘ -// │ -// ┌─────────V────────┐ Processes view.DocumentFragment to text/html and text/plain -// │ clipboardOutput │ and stores the results in data.dataTransfer. -// └─────────┬────────┘ -// │ -// │ DOM dragover -// ┌────────────┐ -// │ │ -// ┌─────────V────────┐ │ -// │ dragging │ │ Updates the drop target marker. -// └─────────┬────────┘ │ -// │ │ -// ┌─────────────└────────────┘ -// │ │ │ -// │ ┌─────────V────────┐ │ -// │ │ dragleave │ │ Removes the drop target marker. -// │ └─────────┬────────┘ │ -// │ │ │ -// ┌───│─────────────┘ │ -// │ │ │ │ -// │ │ ┌─────────V────────┐ │ -// │ │ │ dragenter │ │ Focuses the editor view. -// │ │ └─────────┬────────┘ │ -// │ │ │ │ -// │ │ └────────────┘ -// │ │ -// │ └─────────────┐ -// │ │ │ -// │ │ ┌─────────V────────┐ -// └───┐ │ drop │ (The default handler of the clipboard pipeline). -// │ └─────────┬────────┘ -// │ │ -// │ ┌─────────V────────┐ Resolves the final data.targetRanges. -// │ │ clipboardInput │ Aborts if dropping on dragged content. -// │ └─────────┬────────┘ -// │ │ -// │ ┌─────────V────────┐ -// │ │ clipboardInput │ (The default handler of the clipboard pipeline). -// │ └─────────┬────────┘ -// │ │ -// │ ┌───────────V───────────┐ -// │ │ inputTransformation │ (The default handler of the clipboard pipeline). -// │ └───────────┬───────────┘ -// │ │ -// │ ┌──────────V──────────┐ -// │ │ contentInsertion │ Updates the document selection to drop range. -// │ └──────────┬──────────┘ -// │ │ -// │ ┌──────────V──────────┐ -// │ │ contentInsertion │ (The default handler of the clipboard pipeline). -// │ └──────────┬──────────┘ -// │ │ -// │ ┌──────────V──────────┐ -// │ │ contentInsertion │ Removes the content from the original range if the insertion was successful. -// │ └──────────┬──────────┘ -// │ │ -// └─────────────┐ -// │ -// ┌─────────V────────┐ -// │ dragend │ Removes the drop marker and cleans the state. -// └──────────────────┘ -// -/** - * The drag and drop feature. It works on top of the {@link module:clipboard/clipboardpipeline~ClipboardPipeline}. - * - * Read more about the clipboard integration in the {@glink framework/deep-dive/clipboard clipboard deep-dive} guide. - * - * @internal - */ -class DragDropExperimental extends _ckeditor_ckeditor5_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - constructor() { - super(...arguments); - /** - * A delayed callback removing draggable attributes. - */ - this._clearDraggableAttributesDelayed = (0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.delay)(() => this._clearDraggableAttributes(), 40); - /** - * Whether the dragged content can be dropped only in block context. - */ - // TODO handle drag from other editor instance - // TODO configure to use block, inline or both - this._blockMode = false; - /** - * DOM Emitter. - */ - this._domEmitter = new ((0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.DomEmitterMixin)())(); - } - /** - * @inheritDoc - */ - static get pluginName() { - return 'DragDropExperimental'; - } - /** - * @inheritDoc - */ - static get requires() { - return [_clipboardpipeline__WEBPACK_IMPORTED_MODULE_4__["default"], _ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.Widget, _dragdroptarget__WEBPACK_IMPORTED_MODULE_6__["default"]]; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const view = editor.editing.view; - this._draggedRange = null; - this._draggingUid = ''; - this._draggableElement = null; - view.addObserver(_clipboardobserver__WEBPACK_IMPORTED_MODULE_5__["default"]); - view.addObserver(_ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.MouseObserver); - this._setupDragging(); - this._setupContentInsertionIntegration(); - this._setupClipboardInputIntegration(); - this._setupDraggableAttributeHandling(); - this.listenTo(editor, 'change:isReadOnly', (evt, name, isReadOnly) => { - if (isReadOnly) { - this.forceDisabled('readOnlyMode'); - } - else { - this.clearForceDisabled('readOnlyMode'); - } - }); - this.on('change:isEnabled', (evt, name, isEnabled) => { - if (!isEnabled) { - this._finalizeDragging(false); - } - }); - if (_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.env.isAndroid) { - this.forceDisabled('noAndroidSupport'); - } - } - /** - * @inheritDoc - */ - destroy() { - if (this._draggedRange) { - this._draggedRange.detach(); - this._draggedRange = null; - } - if (this._previewContainer) { - this._previewContainer.remove(); - } - this._domEmitter.stopListening(); - this._clearDraggableAttributesDelayed.cancel(); - return super.destroy(); - } - /** - * Drag and drop events handling. - */ - _setupDragging() { - const editor = this.editor; - const model = editor.model; - const view = editor.editing.view; - const viewDocument = view.document; - const dragDropTarget = editor.plugins.get(_dragdroptarget__WEBPACK_IMPORTED_MODULE_6__["default"]); - // The handler for the drag start; it is responsible for setting data transfer object. - this.listenTo(viewDocument, 'dragstart', (evt, data) => { - // Don't drag the editable element itself. - if (data.target && data.target.is('editableElement')) { - data.preventDefault(); - return; - } - this._prepareDraggedRange(data.target); - if (!this._draggedRange) { - data.preventDefault(); - return; - } - this._draggingUid = (0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.uid)(); - data.dataTransfer.effectAllowed = this.isEnabled ? 'copyMove' : 'copy'; - data.dataTransfer.setData('application/ckeditor5-dragging-uid', this._draggingUid); - const draggedSelection = model.createSelection(this._draggedRange.toRange()); - const content = editor.data.toView(model.getSelectedContent(draggedSelection)); - viewDocument.fire('clipboardOutput', { - dataTransfer: data.dataTransfer, - content, - method: 'dragstart' - }); - this._updatePreview(data.dataTransfer); - data.stopPropagation(); - if (!this.isEnabled) { - this._draggedRange.detach(); - this._draggedRange = null; - this._draggingUid = ''; - } - }, { priority: 'low' }); - // The handler for finalizing drag and drop. It should always be triggered after dragging completes - // even if it was completed in a different application. - // Note: This is not fired if source text node got removed while downcasting a marker. - this.listenTo(viewDocument, 'dragend', (evt, data) => { - this._finalizeDragging(!data.dataTransfer.isCanceled && data.dataTransfer.dropEffect == 'move'); - }, { priority: 'low' }); - // Reset block dragging mode even if dropped outside the editable. - this._domEmitter.listenTo(_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.global.document, 'dragend', () => { - this._blockMode = false; - }, { useCapture: true }); - // Dragging over the editable. - this.listenTo(viewDocument, 'dragenter', () => { - if (!this.isEnabled) { - return; - } - view.focus(); - }); - // Dragging out of the editable. - this.listenTo(viewDocument, 'dragleave', () => { - // We do not know if the mouse left the editor or just some element in it, so let us wait a few milliseconds - // to check if 'dragover' is not fired. - dragDropTarget.removeDropMarkerDelayed(); - }); - // Handler for moving dragged content over the target area. - this.listenTo(viewDocument, 'dragging', (evt, data) => { - if (!this.isEnabled) { - data.dataTransfer.dropEffect = 'none'; - return; - } - const { clientX, clientY } = data.domEvent; - dragDropTarget.updateDropMarker(data.target, data.targetRanges, clientX, clientY, this._blockMode); - // If this is content being dragged from another editor, moving out of current editor instance - // is not possible until 'dragend' event case will be fixed. - if (!this._draggedRange) { - data.dataTransfer.dropEffect = 'copy'; - } - // In Firefox it is already set and effect allowed remains the same as originally set. - if (!_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.env.isGecko) { - if (data.dataTransfer.effectAllowed == 'copy') { - data.dataTransfer.dropEffect = 'copy'; - } - else if (['all', 'copyMove'].includes(data.dataTransfer.effectAllowed)) { - data.dataTransfer.dropEffect = 'move'; - } - } - evt.stop(); - }, { priority: 'low' }); - } - /** - * Integration with the `clipboardInput` event. - */ - _setupClipboardInputIntegration() { - const editor = this.editor; - const view = editor.editing.view; - const viewDocument = view.document; - const dragDropTarget = editor.plugins.get(_dragdroptarget__WEBPACK_IMPORTED_MODULE_6__["default"]); - // Update the event target ranges and abort dropping if dropping over itself. - this.listenTo(viewDocument, 'clipboardInput', (evt, data) => { - if (data.method != 'drop') { - return; - } - const { clientX, clientY } = data.domEvent; - const targetRange = dragDropTarget.getFinalDropRange(data.target, data.targetRanges, clientX, clientY, this._blockMode); - /* istanbul ignore if -- @preserve */ - if (!targetRange) { - this._finalizeDragging(false); - evt.stop(); - return; - } - // Since we cannot rely on the drag end event, we must check if the local drag range is from the current drag and drop - // or it is from some previous not cleared one. - if (this._draggedRange && this._draggingUid != data.dataTransfer.getData('application/ckeditor5-dragging-uid')) { - this._draggedRange.detach(); - this._draggedRange = null; - this._draggingUid = ''; - } - // Do not do anything if some content was dragged within the same document to the same position. - const isMove = getFinalDropEffect(data.dataTransfer) == 'move'; - if (isMove && this._draggedRange && this._draggedRange.containsRange(targetRange, true)) { - this._finalizeDragging(false); - evt.stop(); - return; - } - // Override the target ranges with the one adjusted to the best one for a drop. - data.targetRanges = [editor.editing.mapper.toViewRange(targetRange)]; - }, { priority: 'high' }); - } - /** - * Integration with the `contentInsertion` event of the clipboard pipeline. - */ - _setupContentInsertionIntegration() { - const clipboardPipeline = this.editor.plugins.get(_clipboardpipeline__WEBPACK_IMPORTED_MODULE_4__["default"]); - clipboardPipeline.on('contentInsertion', (evt, data) => { - if (!this.isEnabled || data.method !== 'drop') { - return; - } - // Update the selection to the target range in the same change block to avoid selection post-fixing - // and to be able to clone text attributes for plain text dropping. - const ranges = data.targetRanges.map(viewRange => this.editor.editing.mapper.toModelRange(viewRange)); - this.editor.model.change(writer => writer.setSelection(ranges)); - }, { priority: 'high' }); - clipboardPipeline.on('contentInsertion', (evt, data) => { - if (!this.isEnabled || data.method !== 'drop') { - return; - } - // Remove dragged range content, remove markers, clean after dragging. - const isMove = getFinalDropEffect(data.dataTransfer) == 'move'; - // Whether any content was inserted (insertion might fail if the schema is disallowing some elements - // (for example an image caption allows only the content of a block but not blocks themselves. - // Some integrations might not return valid range (i.e., table pasting). - const isSuccess = !data.resultRange || !data.resultRange.isCollapsed; - this._finalizeDragging(isSuccess && isMove); - }, { priority: 'lowest' }); - } - /** - * Adds listeners that add the `draggable` attribute to the elements while the mouse button is down so the dragging could start. - */ - _setupDraggableAttributeHandling() { - const editor = this.editor; - const view = editor.editing.view; - const viewDocument = view.document; - // Add the 'draggable' attribute to the widget while pressing the selection handle. - // This is required for widgets to be draggable. In Chrome it will enable dragging text nodes. - this.listenTo(viewDocument, 'mousedown', (evt, data) => { - // The lack of data can be caused by editor tests firing fake mouse events. This should not occur - // in real-life scenarios but this greatly simplifies editor tests that would otherwise fail a lot. - if (_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.env.isAndroid || !data) { - return; - } - this._clearDraggableAttributesDelayed.cancel(); - // Check if this is a mousedown over the widget (but not a nested editable). - let draggableElement = findDraggableWidget(data.target); - // Note: There is a limitation that if more than a widget is selected (a widget and some text) - // and dragging starts on the widget, then only the widget is dragged. - // If this was not a widget then we should check if we need to drag some text content. - // In Chrome set a 'draggable' attribute on closest editable to allow immediate dragging of the selected text range. - // In Firefox this is not needed. In Safari it makes the whole editable draggable (not just textual content). - // Disabled in read-only mode because draggable="true" + contenteditable="false" results - // in not firing selectionchange event ever, which makes the selection stuck in read-only mode. - if (_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.env.isBlink && !editor.isReadOnly && !draggableElement && !viewDocument.selection.isCollapsed) { - const selectedElement = viewDocument.selection.getSelectedElement(); - if (!selectedElement || !(0,_ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.isWidget)(selectedElement)) { - draggableElement = viewDocument.selection.editableElement; - } - } - if (draggableElement) { - view.change(writer => { - writer.setAttribute('draggable', 'true', draggableElement); - }); - // Keep the reference to the model element in case the view element gets removed while dragging. - this._draggableElement = editor.editing.mapper.toModelElement(draggableElement); - } - }); - // Remove the draggable attribute in case no dragging started (only mousedown + mouseup). - this.listenTo(viewDocument, 'mouseup', () => { - if (!_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.env.isAndroid) { - this._clearDraggableAttributesDelayed(); - } - }); - } - /** - * Removes the `draggable` attribute from the element that was used for dragging. - */ - _clearDraggableAttributes() { - const editing = this.editor.editing; - editing.view.change(writer => { - // Remove 'draggable' attribute. - if (this._draggableElement && this._draggableElement.root.rootName != '$graveyard') { - writer.removeAttribute('draggable', editing.mapper.toViewElement(this._draggableElement)); - } - this._draggableElement = null; - }); - } - /** - * Deletes the dragged content from its original range and clears the dragging state. - * - * @param moved Whether the move succeeded. - */ - _finalizeDragging(moved) { - const editor = this.editor; - const model = editor.model; - const dragDropTarget = editor.plugins.get(_dragdroptarget__WEBPACK_IMPORTED_MODULE_6__["default"]); - dragDropTarget.removeDropMarker(); - this._clearDraggableAttributes(); - if (editor.plugins.has('WidgetToolbarRepository')) { - const widgetToolbarRepository = editor.plugins.get('WidgetToolbarRepository'); - widgetToolbarRepository.clearForceDisabled('dragDrop'); - } - this._draggingUid = ''; - if (this._previewContainer) { - this._previewContainer.remove(); - this._previewContainer = undefined; - } - if (!this._draggedRange) { - return; - } - // Delete moved content. - if (moved && this.isEnabled) { - model.deleteContent(model.createSelection(this._draggedRange), { doNotAutoparagraph: true }); - } - this._draggedRange.detach(); - this._draggedRange = null; - } - /** - * Sets the dragged source range based on event target and document selection. - */ - _prepareDraggedRange(target) { - const editor = this.editor; - const model = editor.model; - const selection = model.document.selection; - // Check if this is dragstart over the widget (but not a nested editable). - const draggableWidget = target ? findDraggableWidget(target) : null; - if (draggableWidget) { - const modelElement = editor.editing.mapper.toModelElement(draggableWidget); - this._draggedRange = _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.LiveRange.fromRange(model.createRangeOn(modelElement)); - this._blockMode = model.schema.isBlock(modelElement); - // Disable toolbars so they won't obscure the drop area. - if (editor.plugins.has('WidgetToolbarRepository')) { - const widgetToolbarRepository = editor.plugins.get('WidgetToolbarRepository'); - widgetToolbarRepository.forceDisabled('dragDrop'); - } - } - // If this was not a widget we should check if we need to drag some text content. - else if (!selection.isCollapsed || selection.getFirstPosition().parent.isEmpty) { - const blocks = Array.from(selection.getSelectedBlocks()); - if (blocks.length > 1) { - this._draggedRange = _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.LiveRange.fromRange(model.createRange(model.createPositionBefore(blocks[0]), model.createPositionAfter(blocks[blocks.length - 1]))); - model.change(writer => writer.setSelection(this._draggedRange.toRange())); - this._blockMode = true; - // TODO block mode for dragging from outside editor? or inline? or both? - } - else if (blocks.length == 1) { - const draggedRange = selection.getFirstRange(); - const blockRange = model.createRange(model.createPositionBefore(blocks[0]), model.createPositionAfter(blocks[0])); - if (draggedRange.start.isTouching(blockRange.start) && - draggedRange.end.isTouching(blockRange.end)) { - this._draggedRange = _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.LiveRange.fromRange(blockRange); - this._blockMode = true; - } - else { - this._draggedRange = _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.LiveRange.fromRange(selection.getFirstRange()); - this._blockMode = false; - } - } - } - } - /** - * Updates the dragged preview image. - */ - _updatePreview(dataTransfer) { - const view = this.editor.editing.view; - const editable = view.document.selection.editableElement; - const domEditable = view.domConverter.mapViewToDom(editable); - const computedStyle = _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.global.window.getComputedStyle(domEditable); - if (!this._previewContainer) { - this._previewContainer = (0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.createElement)(_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.global.document, 'div', { - style: 'position: fixed; left: -999999px;' - }); - _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.global.document.body.appendChild(this._previewContainer); - } - else { - this._previewContainer.removeChild(this._previewContainer.firstElementChild); - } - const preview = (0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.createElement)(_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.global.document, 'div'); - preview.className = 'ck ck-content'; - preview.style.width = computedStyle.width; - preview.innerHTML = dataTransfer.getData('text/html'); - dataTransfer.setDragImage(preview, 0, 0); - // TODO set x to make dragged widget stick to the mouse cursor - this._previewContainer.appendChild(preview); - } -} -/** - * Returns the drop effect that should be a result of dragging the content. - * This function is handling a quirk when checking the effect in the 'drop' DOM event. - */ -function getFinalDropEffect(dataTransfer) { - if (_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_3__.env.isGecko) { - return dataTransfer.dropEffect; - } - return ['all', 'copyMove'].includes(dataTransfer.effectAllowed) ? 'move' : 'copy'; -} -/** - * Returns a widget element that should be dragged. - */ -function findDraggableWidget(target) { - // This is directly an editable so not a widget for sure. - if (target.is('editableElement')) { - return null; - } - // TODO: Let's have a isWidgetSelectionHandleDomElement() helper in ckeditor5-widget utils. - if (target.hasClass('ck-widget__selection-handle')) { - return target.findAncestor(_ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.isWidget); - } - // Direct hit on a widget. - if ((0,_ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.isWidget)(target)) { - return target; - } - // Find closest ancestor that is either a widget or an editable element... - const ancestor = target.findAncestor(node => (0,_ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.isWidget)(node) || node.is('editableElement')); - // ...and if closer was the widget then enable dragging it. - if ((0,_ckeditor_ckeditor5_widget__WEBPACK_IMPORTED_MODULE_2__.isWidget)(ancestor)) { - return ancestor; - } - return null; -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdroptarget.js": -/*!**************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdroptarget.js ***! - \**************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ DragDropTarget) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core */ "./node_modules/@ckeditor/ckeditor5-core/src/index.js"); -/* harmony import */ var _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils */ "./node_modules/@ckeditor/ckeditor5-utils/src/index.js"); -/* harmony import */ var _lineview__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lineview */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/lineview.js"); -/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lodash-es */ "./node_modules/lodash-es/throttle.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module clipboard/dragdroptarget - */ -/* istanbul ignore file -- @preserve */ - - - - -/** - * Part of the Drag and Drop handling. Responsible for finding and displaying the drop target. - * - * @internal - */ -class DragDropTarget extends _ckeditor_ckeditor5_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - constructor() { - super(...arguments); - /** - * A delayed callback removing the drop marker. - * - * @internal - */ - this.removeDropMarkerDelayed = (0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.delay)(() => this.removeDropMarker(), 40); - /** - * A throttled callback updating the drop marker. - */ - this._updateDropMarkerThrottled = (0,lodash_es__WEBPACK_IMPORTED_MODULE_3__["default"])(targetRange => this._updateDropMarker(targetRange), 40); - /** - * A throttled callback reconverting the drop parker. - */ - this._reconvertMarkerThrottled = (0,lodash_es__WEBPACK_IMPORTED_MODULE_3__["default"])(() => { - if (this.editor.model.markers.has('drop-target')) { - this.editor.editing.reconvertMarker('drop-target'); - } - }, 0); - /** - * The horizontal drop target line view. - */ - this._dropTargetLineView = new _lineview__WEBPACK_IMPORTED_MODULE_2__["default"](); - /** - * DOM Emitter. - */ - this._domEmitter = new ((0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.DomEmitterMixin)())(); - /** - * Map of document scrollable elements. - */ - this._scrollables = new Map(); - } - /** - * @inheritDoc - */ - static get pluginName() { - return 'DragDropTarget'; - } - /** - * @inheritDoc - */ - init() { - this._setupDropMarker(); - } - /** - * @inheritDoc - */ - destroy() { - this._domEmitter.stopListening(); - for (const { resizeObserver } of this._scrollables.values()) { - resizeObserver.destroy(); - } - this._updateDropMarkerThrottled.cancel(); - this.removeDropMarkerDelayed.cancel(); - this._reconvertMarkerThrottled.cancel(); - return super.destroy(); - } - /** - * Finds the drop target range and updates the drop marker. - * - * @internal - */ - updateDropMarker(targetViewElement, targetViewRanges, clientX, clientY, blockMode) { - this.removeDropMarkerDelayed.cancel(); - const targetRange = findDropTargetRange(this.editor, targetViewElement, targetViewRanges, clientX, clientY, blockMode); - /* istanbul ignore else -- @preserve */ - if (targetRange) { - this._updateDropMarkerThrottled(targetRange); - } - } - /** - * Finds the final drop target range. - * - * @internal - */ - getFinalDropRange(targetViewElement, targetViewRanges, clientX, clientY, blockMode) { - const targetRange = findDropTargetRange(this.editor, targetViewElement, targetViewRanges, clientX, clientY, blockMode); - // The dragging markers must be removed after searching for the target range because sometimes - // the target lands on the marker itself. - this.removeDropMarker(); - return targetRange; - } - /** - * Removes the drop target marker. - * - * @internal - */ - removeDropMarker() { - const model = this.editor.model; - this.removeDropMarkerDelayed.cancel(); - this._updateDropMarkerThrottled.cancel(); - this._dropTargetLineView.isVisible = false; - if (model.markers.has('drop-target')) { - model.change(writer => { - writer.removeMarker('drop-target'); - }); - } - } - /** - * Creates downcast conversion for the drop target marker. - */ - _setupDropMarker() { - const editor = this.editor; - editor.ui.view.body.add(this._dropTargetLineView); - // Drop marker conversion for hovering over widgets. - editor.conversion.for('editingDowncast').markerToHighlight({ - model: 'drop-target', - view: { - classes: ['ck-clipboard-drop-target-range'] - } - }); - // Drop marker conversion for in text and block drop target. - editor.conversion.for('editingDowncast').markerToElement({ - model: 'drop-target', - view: (data, { writer }) => { - // Inline drop. - if (editor.model.schema.checkChild(data.markerRange.start, '$text')) { - this._dropTargetLineView.isVisible = false; - return this._createDropTargetPosition(writer); - } - // Block drop. - else { - if (data.markerRange.isCollapsed) { - this._updateDropTargetLine(data.markerRange); - } - else { - this._dropTargetLineView.isVisible = false; - } - } - } - }); - } - /** - * Updates the drop target marker to the provided range. - * - * @param targetRange The range to set the marker to. - */ - _updateDropMarker(targetRange) { - const editor = this.editor; - const markers = editor.model.markers; - editor.model.change(writer => { - if (markers.has('drop-target')) { - if (!markers.get('drop-target').getRange().isEqual(targetRange)) { - writer.updateMarker('drop-target', { range: targetRange }); - } - } - else { - writer.addMarker('drop-target', { - range: targetRange, - usingOperation: false, - affectsData: false - }); - } - }); - } - /** - * Creates the UI element for vertical (in-line) drop target. - */ - _createDropTargetPosition(writer) { - return writer.createUIElement('span', { class: 'ck ck-clipboard-drop-target-position' }, function (domDocument) { - const domElement = this.toDomElement(domDocument); - // Using word joiner to make this marker as high as text and also making text not break on marker. - domElement.append('\u2060', domDocument.createElement('span'), '\u2060'); - return domElement; - }); - } - /** - * Updates the horizontal drop target line. - */ - _updateDropTargetLine(range) { - const editing = this.editor.editing; - const nodeBefore = range.start.nodeBefore; - const nodeAfter = range.start.nodeAfter; - const nodeParent = range.start.parent; - const viewElementBefore = nodeBefore ? editing.mapper.toViewElement(nodeBefore) : null; - const domElementBefore = viewElementBefore ? editing.view.domConverter.mapViewToDom(viewElementBefore) : null; - const viewElementAfter = nodeAfter ? editing.mapper.toViewElement(nodeAfter) : null; - const domElementAfter = viewElementAfter ? editing.view.domConverter.mapViewToDom(viewElementAfter) : null; - const viewElementParent = editing.mapper.toViewElement(nodeParent); - const domElementParent = editing.view.domConverter.mapViewToDom(viewElementParent); - const domScrollableRect = this._getScrollableRect(viewElementParent); - const { scrollX, scrollY } = _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.global.window; - const rectBefore = domElementBefore ? new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.Rect(domElementBefore) : null; - const rectAfter = domElementAfter ? new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.Rect(domElementAfter) : null; - const rectParent = new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.Rect(domElementParent).excludeScrollbarsAndBorders(); - const above = rectBefore ? rectBefore.bottom : rectParent.top; - const below = rectAfter ? rectAfter.top : rectParent.bottom; - const parentStyle = _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.global.window.getComputedStyle(domElementParent); - const top = (above <= below ? (above + below) / 2 : below); - if (domScrollableRect.top < top && top < domScrollableRect.bottom) { - const left = rectParent.left + parseFloat(parentStyle.paddingLeft); - const right = rectParent.right - parseFloat(parentStyle.paddingRight); - const leftClamped = Math.max(left + scrollX, domScrollableRect.left); - const rightClamped = Math.min(right + scrollX, domScrollableRect.right); - this._dropTargetLineView.set({ - isVisible: true, - left: leftClamped, - top: top + scrollY, - width: rightClamped - leftClamped - }); - } - else { - this._dropTargetLineView.isVisible = false; - } - } - /** - * Finds the closest scrollable element rect for the given view element. - */ - _getScrollableRect(viewElement) { - const rootName = viewElement.root.rootName; - let domScrollable; - if (this._scrollables.has(rootName)) { - domScrollable = this._scrollables.get(rootName).domElement; - } - else { - const domElement = this.editor.editing.view.domConverter.mapViewToDom(viewElement); - domScrollable = findScrollableElement(domElement); - this._domEmitter.listenTo(domScrollable, 'scroll', this._reconvertMarkerThrottled, { usePassive: true }); - const resizeObserver = new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.ResizeObserver(domScrollable, this._reconvertMarkerThrottled); - this._scrollables.set(rootName, { - domElement: domScrollable, - resizeObserver - }); - } - return new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.Rect(domScrollable).excludeScrollbarsAndBorders(); - } -} -/** - * Returns fixed selection range for given position and target element. - */ -function findDropTargetRange(editor, targetViewElement, targetViewRanges, clientX, clientY, blockMode) { - const model = editor.model; - const mapper = editor.editing.mapper; - const targetModelElement = getClosestMappedModelElement(editor, targetViewElement); - let modelElement = targetModelElement; - while (modelElement) { - if (!blockMode) { - if (model.schema.checkChild(modelElement, '$text')) { - const targetViewPosition = targetViewRanges ? targetViewRanges[0].start : null; - const targetModelPosition = targetViewPosition ? mapper.toModelPosition(targetViewPosition) : null; - if (targetModelPosition) { - if (model.schema.checkChild(targetModelPosition, '$text')) { - return model.createRange(targetModelPosition); - } - else if (targetViewPosition) { - // This is the case of dropping inside a span wrapper of an inline image. - return findDropTargetRangeForElement(editor, getClosestMappedModelElement(editor, targetViewPosition.parent), clientX, clientY); - } - } - } - else if (model.schema.isInline(modelElement)) { - return findDropTargetRangeForElement(editor, modelElement, clientX, clientY); - } - } - if (model.schema.isBlock(modelElement)) { - return findDropTargetRangeForElement(editor, modelElement, clientX, clientY); - } - else if (model.schema.checkChild(modelElement, '$block')) { - const childNodes = Array.from(modelElement.getChildren()) - .filter((node) => node.is('element') && !isFloatingElement(editor, node)); - let startIndex = 0; - let endIndex = childNodes.length; - while (startIndex < endIndex - 1) { - const middleIndex = Math.floor((startIndex + endIndex) / 2); - const side = findElementSide(editor, childNodes[middleIndex], clientX, clientY); - if (side == 'before') { - endIndex = middleIndex; - } - else { - startIndex = middleIndex; - } - } - return findDropTargetRangeForElement(editor, childNodes[startIndex], clientX, clientY); - } - modelElement = modelElement.parent; - } - console.warn('none:', targetModelElement.name); - return null; -} -/** - * Returns true for elements with floating style set. - */ -function isFloatingElement(editor, modelElement) { - const mapper = editor.editing.mapper; - const domConverter = editor.editing.view.domConverter; - const viewElement = mapper.toViewElement(modelElement); - const domElement = domConverter.mapViewToDom(viewElement); - return _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.global.window.getComputedStyle(domElement).float != 'none'; -} -/** - * Returns target range relative to the given element. - */ -function findDropTargetRangeForElement(editor, modelElement, clientX, clientY) { - const model = editor.model; - return model.createRange(model.createPositionAt(modelElement, findElementSide(editor, modelElement, clientX, clientY))); -} -/** - * Resolves whether drop marker should be before or after the given element. - */ -function findElementSide(editor, modelElement, clientX, clientY) { - const mapper = editor.editing.mapper; - const domConverter = editor.editing.view.domConverter; - const viewElement = mapper.toViewElement(modelElement); - const domElement = domConverter.mapViewToDom(viewElement); - const rect = new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.Rect(domElement); - if (editor.model.schema.isInline(modelElement)) { - return clientX < (rect.left + rect.right) / 2 ? 'before' : 'after'; - } - else { - return clientY < (rect.top + rect.bottom) / 2 ? 'before' : 'after'; - } -} -/** - * Returns the closest model element for the specified view element. - */ -function getClosestMappedModelElement(editor, element) { - const mapper = editor.editing.mapper; - const view = editor.editing.view; - const targetModelElement = mapper.toModelElement(element); - if (targetModelElement) { - return targetModelElement; - } - // Find mapped ancestor if the target is inside not mapped element (for example inline code element). - const viewPosition = view.createPositionBefore(element); - const viewElement = mapper.findMappedViewAncestor(viewPosition); - return mapper.toModelElement(viewElement); -} -/** - * Returns the closest scrollable ancestor DOM element. - * - * It is assumed that `domNode` is attached to the document. - */ -function findScrollableElement(domNode) { - let domElement = domNode; - do { - domElement = domElement.parentElement; - const overflow = _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.global.window.getComputedStyle(domElement).overflowY; - if (overflow == 'auto' || overflow == 'scroll') { - break; - } - } while (domElement.tagName != 'BODY'); - return domElement; -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/index.js": -/*!*****************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/index.js ***! - \*****************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ Clipboard: () => (/* reexport safe */ _clipboard__WEBPACK_IMPORTED_MODULE_0__["default"]), -/* harmony export */ ClipboardPipeline: () => (/* reexport safe */ _clipboardpipeline__WEBPACK_IMPORTED_MODULE_1__["default"]), -/* harmony export */ DragDrop: () => (/* reexport safe */ _dragdrop__WEBPACK_IMPORTED_MODULE_2__["default"]), -/* harmony export */ DragDropBlockToolbar: () => (/* reexport safe */ _dragdropblocktoolbar__WEBPACK_IMPORTED_MODULE_6__["default"]), -/* harmony export */ DragDropExperimental: () => (/* reexport safe */ _dragdropexperimental__WEBPACK_IMPORTED_MODULE_4__["default"]), -/* harmony export */ DragDropTarget: () => (/* reexport safe */ _dragdroptarget__WEBPACK_IMPORTED_MODULE_5__["default"]), -/* harmony export */ PastePlainText: () => (/* reexport safe */ _pasteplaintext__WEBPACK_IMPORTED_MODULE_3__["default"]) -/* harmony export */ }); -/* harmony import */ var _clipboard__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./clipboard */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboard.js"); -/* harmony import */ var _clipboardpipeline__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./clipboardpipeline */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.js"); -/* harmony import */ var _dragdrop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./dragdrop */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdrop.js"); -/* harmony import */ var _pasteplaintext__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./pasteplaintext */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/pasteplaintext.js"); -/* harmony import */ var _dragdropexperimental__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./dragdropexperimental */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdropexperimental.js"); -/* harmony import */ var _dragdroptarget__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./dragdroptarget */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdroptarget.js"); -/* harmony import */ var _dragdropblocktoolbar__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./dragdropblocktoolbar */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdropblocktoolbar.js"); -/* harmony import */ var _augmentation__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./augmentation */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/augmentation.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module clipboard - */ - - - - - - - - - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/lineview.js": -/*!********************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/lineview.js ***! - \********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ LineView) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-ui */ "./node_modules/@ckeditor/ckeditor5-ui/src/index.js"); -/* harmony import */ var _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils */ "./node_modules/@ckeditor/ckeditor5-utils/src/index.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module clipboard/lineview - */ -/* istanbul ignore file -- @preserve */ - - -const toPx = (0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_1__.toUnit)('px'); -/** - * The horizontal drop target line view. - */ -class LineView extends _ckeditor_ckeditor5_ui__WEBPACK_IMPORTED_MODULE_0__.View { - /** - * @inheritDoc - */ - constructor() { - super(); - const bind = this.bindTemplate; - this.set({ - isVisible: false, - left: null, - top: null, - width: null - }); - this.setTemplate({ - tag: 'div', - attributes: { - class: [ - 'ck', - 'ck-clipboard-drop-target-line', - bind.if('isVisible', 'ck-hidden', value => !value) - ], - style: { - left: bind.to('left', left => toPx(left)), - top: bind.to('top', top => toPx(top)), - width: bind.to('width', width => toPx(width)) - } - } - }); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/pasteplaintext.js": -/*!**************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/pasteplaintext.js ***! - \**************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ PastePlainText) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-core */ "./node_modules/@ckeditor/ckeditor5-core/src/index.js"); -/* harmony import */ var _clipboardobserver__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./clipboardobserver */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardobserver.js"); -/* harmony import */ var _clipboardpipeline__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./clipboardpipeline */ "./node_modules/@ckeditor/ckeditor5-clipboard/src/clipboardpipeline.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module clipboard/pasteplaintext - */ - - - -/** - * The plugin detects the user's intention to paste plain text. - * - * For example, it detects the Ctrl/Cmd + Shift + V keystroke. - */ -class PastePlainText extends _ckeditor_ckeditor5_core__WEBPACK_IMPORTED_MODULE_0__.Plugin { - /** - * @inheritDoc - */ - static get pluginName() { - return 'PastePlainText'; - } - /** - * @inheritDoc - */ - static get requires() { - return [_clipboardpipeline__WEBPACK_IMPORTED_MODULE_2__["default"]]; - } - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const model = editor.model; - const view = editor.editing.view; - const viewDocument = view.document; - const selection = model.document.selection; - let shiftPressed = false; - view.addObserver(_clipboardobserver__WEBPACK_IMPORTED_MODULE_1__["default"]); - this.listenTo(viewDocument, 'keydown', (evt, data) => { - shiftPressed = data.shiftKey; - }); - editor.plugins.get(_clipboardpipeline__WEBPACK_IMPORTED_MODULE_2__["default"]).on('contentInsertion', (evt, data) => { - // Plain text can be determined based on the event flag (#7799) or auto-detection (#1006). If detected, - // preserve selection attributes on pasted items. - if (!shiftPressed && !isPlainTextFragment(data.content, model.schema)) { - return; - } - model.change(writer => { - // Formatting attributes should be preserved. - const textAttributes = Array.from(selection.getAttributes()) - .filter(([key]) => model.schema.getAttributeProperties(key).isFormatting); - if (!selection.isCollapsed) { - model.deleteContent(selection, { doNotAutoparagraph: true }); - } - // Also preserve other attributes if they survived the content deletion (because they were not fully selected). - // For example linkHref is not a formatting attribute but it should be preserved if pasted text was in the middle - // of a link. - textAttributes.push(...selection.getAttributes()); - const range = writer.createRangeIn(data.content); - for (const item of range.getItems()) { - if (item.is('$textProxy')) { - writer.setAttributes(textAttributes, item); - } - } - }); - }); - } -} -/** - * Returns true if specified `documentFragment` represents a plain text. - */ -function isPlainTextFragment(documentFragment, schema) { - if (documentFragment.childCount > 1) { - return false; - } - const child = documentFragment.getChild(0); - if (schema.isObject(child)) { - return false; - } - return Array.from(child.getAttributeKeys()).length == 0; -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/normalizeclipboarddata.js": -/*!****************************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/normalizeclipboarddata.js ***! - \****************************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ normalizeClipboardData) -/* harmony export */ }); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module clipboard/utils/normalizeclipboarddata - */ -/** - * Removes some popular browser quirks out of the clipboard data (HTML). - * Removes all HTML comments. These are considered an internal thing and it makes little sense if they leak into the editor data. - * - * @param data The HTML data to normalize. - * @returns Normalized HTML. - */ -function normalizeClipboardData(data) { - return data - .replace(/(\s+)<\/span>/g, (fullMatch, spaces) => { - // Handle the most popular and problematic case when even a single space becomes an nbsp;. - // Decode those to normal spaces. Read more in https://github.com/ckeditor/ckeditor5-clipboard/issues/2. - if (spaces.length == 1) { - return ' '; - } - return spaces; - }) - // Remove all HTML comments. - .replace(//g, ''); -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/plaintexttohtml.js": -/*!*********************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/plaintexttohtml.js ***! - \*********************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ plainTextToHtml) -/* harmony export */ }); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module clipboard/utils/plaintexttohtml - */ -/** - * Converts plain text to its HTML-ized version. - * - * @param text The plain text to convert. - * @returns HTML generated from the plain text. - */ -function plainTextToHtml(text) { - text = text - // Encode <>. - .replace(//g, '>') - // Creates a paragraph for each double line break. - .replace(/\r?\n\r?\n/g, '

') - // Creates a line break for each single line break. - .replace(/\r?\n/g, '
') - // Replace tabs with four spaces. - .replace(/\t/g, '    ') - // Preserve trailing spaces (only the first and last one – the rest is handled below). - .replace(/^\s/, ' ') - .replace(/\s$/, ' ') - // Preserve other subsequent spaces now. - .replace(/\s\s/g, '  '); - if (text.includes('

') || text.includes('
')) { - // If we created paragraphs above, add the trailing ones. - text = `

${text}

`; - } - // TODO: - // * What about '\nfoo' vs ' foo'? - return text; -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/viewtoplaintext.js": -/*!*********************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-clipboard/src/utils/viewtoplaintext.js ***! - \*********************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ viewToPlainText) -/* harmony export */ }); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -// Elements which should not have empty-line padding. -// Most `view.ContainerElement` want to be separate by new-line, but some are creating one structure -// together (like `
  • `) so it is better to separate them by only one "\n". -const smallPaddingElements = ['figcaption', 'li']; -/** - * Converts {@link module:engine/view/item~Item view item} and all of its children to plain text. - * - * @param viewItem View item to convert. - * @returns Plain text representation of `viewItem`. - */ -function viewToPlainText(viewItem) { - let text = ''; - if (viewItem.is('$text') || viewItem.is('$textProxy')) { - // If item is `Text` or `TextProxy` simple take its text data. - text = viewItem.data; - } - else if (viewItem.is('element', 'img') && viewItem.hasAttribute('alt')) { - // Special case for images - use alt attribute if it is provided. - text = viewItem.getAttribute('alt'); - } - else if (viewItem.is('element', 'br')) { - // A soft break should be converted into a single line break (#8045). - text = '\n'; - } - else { - // Other elements are document fragments, attribute elements or container elements. - // They don't have their own text value, so convert their children. - let prev = null; - for (const child of viewItem.getChildren()) { - const childText = viewToPlainText(child); - // Separate container element children with one or more new-line characters. - if (prev && (prev.is('containerElement') || child.is('containerElement'))) { - if (smallPaddingElements.includes(prev.name) || - smallPaddingElements.includes(child.name)) { - text += '\n'; - } - else { - text += '\n\n'; - } - } - text += childText; - prev = child; - } - } - return text; -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-core/src/augmentation.js": -/*!*******************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-core/src/augmentation.js ***! - \*******************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ - - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-core/src/command.js": -/*!**************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-core/src/command.js ***! - \**************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Command) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils */ "./node_modules/@ckeditor/ckeditor5-utils/src/index.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module core/command - */ - -/** - * Base class for the CKEditor commands. - * - * Commands are the main way to manipulate the editor contents and state. They are mostly used by UI elements (or by other - * commands) to make changes in the model. Commands are available in every part of the code that has access to - * the {@link module:core/editor/editor~Editor editor} instance. - * - * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}. - * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}. - * - * By default, commands are disabled when the editor is in the {@link module:core/editor/editor~Editor#isReadOnly read-only} mode - * but commands with the {@link module:core/command~Command#affectsData `affectsData`} flag set to `false` will not be disabled. - */ -class Command extends (0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.ObservableMixin)() { - /** - * Creates a new `Command` instance. - * - * @param editor The editor on which this command will be used. - */ - constructor(editor) { - super(); - this.editor = editor; - this.set('value', undefined); - this.set('isEnabled', false); - this._affectsData = true; - this._isEnabledBasedOnSelection = true; - this._disableStack = new Set(); - this.decorate('execute'); - // By default, every command is refreshed when changes are applied to the model. - this.listenTo(this.editor.model.document, 'change', () => { - this.refresh(); - }); - this.listenTo(editor, 'change:isReadOnly', () => { - this.refresh(); - }); - // By default, commands are disabled if the selection is in non-editable place or editor is in read-only mode. - this.on('set:isEnabled', evt => { - if (!this.affectsData) { - return; - } - // Checking `editor.isReadOnly` is needed for all commands that have `_isEnabledBasedOnSelection == false`. - // E.g. undo does not base on selection, but affects data and should be disabled when the editor is in read-only mode. - if (editor.isReadOnly || this._isEnabledBasedOnSelection && !editor.model.canEditAt(editor.model.document.selection)) { - evt.return = false; - evt.stop(); - } - }, { priority: 'highest' }); - this.on('execute', evt => { - if (!this.isEnabled) { - evt.stop(); - } - }, { priority: 'high' }); - } - /** - * A flag indicating whether a command execution changes the editor data or not. - * - * Commands with `affectsData` set to `false` will not be automatically disabled in - * the {@link module:core/editor/editor~Editor#isReadOnly read-only mode} and - * {@glink features/read-only#related-features other editor modes} with restricted user write permissions. - * - * **Note:** You do not have to set it for your every command. It is `true` by default. - * - * @default true - */ - get affectsData() { - return this._affectsData; - } - set affectsData(affectsData) { - this._affectsData = affectsData; - } - /** - * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties - * in this method. - * - * This method is automatically called when - * {@link module:engine/model/document~Document#event:change any changes are applied to the document}. - */ - refresh() { - this.isEnabled = true; - } - /** - * Disables the command. - * - * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed - * (e.g. the feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command. - * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}. - * - * Disabling and enabling a command: - * - * ```ts - * command.isEnabled; // -> true - * command.forceDisabled( 'MyFeature' ); - * command.isEnabled; // -> false - * command.clearForceDisabled( 'MyFeature' ); - * command.isEnabled; // -> true - * ``` - * - * Command disabled by multiple features: - * - * ```ts - * command.forceDisabled( 'MyFeature' ); - * command.forceDisabled( 'OtherFeature' ); - * command.clearForceDisabled( 'MyFeature' ); - * command.isEnabled; // -> false - * command.clearForceDisabled( 'OtherFeature' ); - * command.isEnabled; // -> true - * ``` - * - * Multiple disabling with the same identifier is redundant: - * - * ```ts - * command.forceDisabled( 'MyFeature' ); - * command.forceDisabled( 'MyFeature' ); - * command.clearForceDisabled( 'MyFeature' ); - * command.isEnabled; // -> true - * ``` - * - * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands, - * so the command might be still disabled after {@link #clearForceDisabled} was used. - * - * @param id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command. - */ - forceDisabled(id) { - this._disableStack.add(id); - if (this._disableStack.size == 1) { - this.on('set:isEnabled', forceDisable, { priority: 'highest' }); - this.isEnabled = false; - } - } - /** - * Clears forced disable previously set through {@link #forceDisabled}. See {@link #forceDisabled}. - * - * @param id Unique identifier, equal to the one passed in {@link #forceDisabled} call. - */ - clearForceDisabled(id) { - this._disableStack.delete(id); - if (this._disableStack.size == 0) { - this.off('set:isEnabled', forceDisable); - this.refresh(); - } - } - /** - * Executes the command. - * - * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`} - * to the command. - * - * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`). - * This behavior is implemented by a high priority listener to the {@link #event:execute} event. - * - * In order to see how to disable a command from "outside" see the {@link #isEnabled} documentation. - * - * This method may return a value, which would be forwarded all the way down to the - * {@link module:core/editor/editor~Editor#execute `editor.execute()`}. - * - * @fires execute - */ - execute(...args) { return undefined; } - /** - * Destroys the command. - */ - destroy() { - this.stopListening(); - } -} -/** - * Helper function that forces command to be disabled. - */ -function forceDisable(evt) { - evt.return = false; - evt.stop(); -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-core/src/commandcollection.js": -/*!************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-core/src/commandcollection.js ***! - \************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ CommandCollection) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils */ "./node_modules/@ckeditor/ckeditor5-utils/src/index.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module core/commandcollection - */ - -/** - * Collection of commands. Its instance is available in {@link module:core/editor/editor~Editor#commands `editor.commands`}. - */ -class CommandCollection { - /** - * Creates collection instance. - */ - constructor() { - this._commands = new Map(); - } - /** - * Registers a new command. - * - * @param commandName The name of the command. - */ - add(commandName, command) { - this._commands.set(commandName, command); - } - /** - * Retrieves a command from the collection. - * - * @param commandName The name of the command. - */ - get(commandName) { - return this._commands.get(commandName); - } - /** - * Executes a command. - * - * @param commandName The name of the command. - * @param commandParams Command parameters. - * @returns The value returned by the {@link module:core/command~Command#execute `command.execute()`}. - */ - execute(commandName, ...commandParams) { - const command = this.get(commandName); - if (!command) { - /** - * Command does not exist. - * - * @error commandcollection-command-not-found - * @param commandName Name of the command. - */ - throw new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.CKEditorError('commandcollection-command-not-found', this, { commandName }); - } - return command.execute(...commandParams); - } - /** - * Returns iterator of command names. - */ - *names() { - yield* this._commands.keys(); - } - /** - * Returns iterator of command instances. - */ - *commands() { - yield* this._commands.values(); - } - /** - * Iterable interface. - * - * Returns `[ commandName, commandInstance ]` pairs. - */ - [Symbol.iterator]() { - return this._commands[Symbol.iterator](); - } - /** - * Destroys all collection commands. - */ - destroy() { - for (const command of this.commands()) { - command.destroy(); - } - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-core/src/context.js": -/*!**************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-core/src/context.js ***! - \**************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Context) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils */ "./node_modules/@ckeditor/ckeditor5-utils/src/index.js"); -/* harmony import */ var _plugincollection__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./plugincollection */ "./node_modules/@ckeditor/ckeditor5-core/src/plugincollection.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module core/context - */ - - -/** - * Provides a common, higher-level environment for solutions that use multiple {@link module:core/editor/editor~Editor editors} - * or plugins that work outside the editor. Use it instead of {@link module:core/editor/editor~Editor.create `Editor.create()`} - * in advanced application integrations. - * - * All configuration options passed to a context will be used as default options for the editor instances initialized in that context. - * - * {@link module:core/contextplugin~ContextPlugin Context plugins} passed to a context instance will be shared among all - * editor instances initialized in this context. These will be the same plugin instances for all the editors. - * - * **Note:** The context can only be initialized with {@link module:core/contextplugin~ContextPlugin context plugins} - * (e.g. [comments](https://ckeditor.com/collaboration/comments/)). Regular {@link module:core/plugin~Plugin plugins} require an - * editor instance to work and cannot be added to a context. - * - * **Note:** You can add a context plugin to an editor instance, though. - * - * If you are using multiple editor instances on one page and use any context plugins, create a context to share the configuration and - * plugins among these editors. Some plugins will use the information about all existing editors to better integrate between them. - * - * If you are using plugins that do not require an editor to work (e.g. [comments](https://ckeditor.com/collaboration/comments/)), - * enable and configure them using the context. - * - * If you are using only a single editor on each page, use {@link module:core/editor/editor~Editor.create `Editor.create()`} instead. - * In such a case, a context instance will be created by the editor instance in a transparent way. - * - * See {@link ~Context.create `Context.create()`} for usage examples. - */ -class Context { - /** - * Creates a context instance with a given configuration. - * - * Usually not to be used directly. See the static {@link module:core/context~Context.create `create()`} method. - * - * @param config The context configuration. - */ - constructor(config) { - /** - * Reference to the editor which created the context. - * Null when the context was created outside of the editor. - * - * It is used to destroy the context when removing the editor that has created the context. - */ - this._contextOwner = null; - this.config = new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.Config(config, this.constructor.defaultConfig); - const availablePlugins = this.constructor.builtinPlugins; - this.config.define('plugins', availablePlugins); - this.plugins = new _plugincollection__WEBPACK_IMPORTED_MODULE_1__["default"](this, availablePlugins); - const languageConfig = this.config.get('language') || {}; - this.locale = new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.Locale({ - uiLanguage: typeof languageConfig === 'string' ? languageConfig : languageConfig.ui, - contentLanguage: this.config.get('language.content') - }); - this.t = this.locale.t; - this.editors = new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.Collection(); - } - /** - * Loads and initializes plugins specified in the configuration. - * - * @returns A promise which resolves once the initialization is completed, providing an array of loaded plugins. - */ - initPlugins() { - const plugins = this.config.get('plugins') || []; - const substitutePlugins = this.config.get('substitutePlugins') || []; - // Plugins for substitution should be checked as well. - for (const Plugin of plugins.concat(substitutePlugins)) { - if (typeof Plugin != 'function') { - /** - * Only a constructor function is allowed as a {@link module:core/contextplugin~ContextPlugin context plugin}. - * - * @error context-initplugins-constructor-only - */ - throw new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.CKEditorError('context-initplugins-constructor-only', null, { Plugin }); - } - if (Plugin.isContextPlugin !== true) { - /** - * Only a plugin marked as a {@link module:core/contextplugin~ContextPlugin.isContextPlugin context plugin} - * is allowed to be used with a context. - * - * @error context-initplugins-invalid-plugin - */ - throw new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.CKEditorError('context-initplugins-invalid-plugin', null, { Plugin }); - } - } - return this.plugins.init(plugins, [], substitutePlugins); - } - /** - * Destroys the context instance and all editors used with the context, - * releasing all resources used by the context. - * - * @returns A promise that resolves once the context instance is fully destroyed. - */ - destroy() { - return Promise.all(Array.from(this.editors, editor => editor.destroy())) - .then(() => this.plugins.destroy()); - } - /** - * Adds a reference to the editor which is used with this context. - * - * When the given editor has created the context, the reference to this editor will be stored - * as a {@link ~Context#_contextOwner}. - * - * This method should only be used by the editor. - * - * @internal - * @param isContextOwner Stores the given editor as a context owner. - */ - _addEditor(editor, isContextOwner) { - if (this._contextOwner) { - /** - * Cannot add multiple editors to the context which is created by the editor. - * - * @error context-addeditor-private-context - */ - throw new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.CKEditorError('context-addeditor-private-context'); - } - this.editors.add(editor); - if (isContextOwner) { - this._contextOwner = editor; - } - } - /** - * Removes a reference to the editor which was used with this context. - * When the context was created by the given editor, the context will be destroyed. - * - * This method should only be used by the editor. - * - * @internal - * @return A promise that resolves once the editor is removed from the context or when the context was destroyed. - */ - _removeEditor(editor) { - if (this.editors.has(editor)) { - this.editors.remove(editor); - } - if (this._contextOwner === editor) { - return this.destroy(); - } - return Promise.resolve(); - } - /** - * Returns the context configuration which will be copied to the editors created using this context. - * - * The configuration returned by this method has the plugins configuration removed — plugins are shared with all editors - * through another mechanism. - * - * This method should only be used by the editor. - * - * @internal - * @returns Configuration as a plain object. - */ - _getEditorConfig() { - const result = {}; - for (const name of this.config.names()) { - if (!['plugins', 'removePlugins', 'extraPlugins'].includes(name)) { - result[name] = this.config.get(name); - } - } - return result; - } - /** - * Creates and initializes a new context instance. - * - * ```ts - * const commonConfig = { ... }; // Configuration for all the plugins and editors. - * const editorPlugins = [ ... ]; // Regular plugins here. - * - * Context - * .create( { - * // Only context plugins here. - * plugins: [ ... ], - * - * // Configure the language for all the editors (it cannot be overwritten). - * language: { ... }, - * - * // Configuration for context plugins. - * comments: { ... }, - * ... - * - * // Default configuration for editor plugins. - * toolbar: { ... }, - * image: { ... }, - * ... - * } ) - * .then( context => { - * const promises = []; - * - * promises.push( ClassicEditor.create( - * document.getElementById( 'editor1' ), - * { - * editorPlugins, - * context - * } - * ) ); - * - * promises.push( ClassicEditor.create( - * document.getElementById( 'editor2' ), - * { - * editorPlugins, - * context, - * toolbar: { ... } // You can overwrite the configuration of the context. - * } - * ) ); - * - * return Promise.all( promises ); - * } ); - * ``` - * - * @param config The context configuration. - * @returns A promise resolved once the context is ready. The promise resolves with the created context instance. - */ - static create(config) { - return new Promise(resolve => { - const context = new this(config); - resolve(context.initPlugins().then(() => context)); - }); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-core/src/contextplugin.js": -/*!********************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-core/src/contextplugin.js ***! - \********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ ContextPlugin) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils */ "./node_modules/@ckeditor/ckeditor5-utils/src/index.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module core/contextplugin - */ - -/** - * The base class for {@link module:core/context~Context} plugin classes. - * - * A context plugin can either be initialized for an {@link module:core/editor/editor~Editor editor} or for - * a {@link module:core/context~Context context}. In other words, it can either - * work within one editor instance or with one or more editor instances that use a single context. - * It is the context plugin's role to implement handling for both modes. - * - * There are a few rules for interaction between the editor plugins and context plugins: - * - * * A context plugin can require another context plugin. - * * An {@link module:core/plugin~Plugin editor plugin} can require a context plugin. - * * A context plugin MUST NOT require an {@link module:core/plugin~Plugin editor plugin}. - */ -class ContextPlugin extends (0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.ObservableMixin)() { - /** - * Creates a new plugin instance. - */ - constructor(context) { - super(); - this.context = context; - } - /** - * @inheritDoc - */ - destroy() { - this.stopListening(); - } - /** - * @inheritDoc - */ - static get isContextPlugin() { - return true; - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-core/src/editingkeystrokehandler.js": -/*!******************************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-core/src/editingkeystrokehandler.js ***! - \******************************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ EditingKeystrokeHandler) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils */ "./node_modules/@ckeditor/ckeditor5-utils/src/index.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module core/editingkeystrokehandler - */ - -/** - * A keystroke handler for editor editing. Its instance is available - * in {@link module:core/editor/editor~Editor#keystrokes} so plugins - * can register their keystrokes. - * - * E.g. an undo plugin would do this: - * - * ```ts - * editor.keystrokes.set( 'Ctrl+Z', 'undo' ); - * editor.keystrokes.set( 'Ctrl+Shift+Z', 'redo' ); - * editor.keystrokes.set( 'Ctrl+Y', 'redo' ); - * ``` - */ -class EditingKeystrokeHandler extends _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.KeystrokeHandler { - /** - * Creates an instance of the keystroke handler. - */ - constructor(editor) { - super(); - this.editor = editor; - } - /** - * Registers a handler for the specified keystroke. - * - * The handler can be specified as a command name or a callback. - * - * @param keystroke Keystroke defined in a format accepted by - * the {@link module:utils/keyboard~parseKeystroke} function. - * @param callback If a string is passed, then the keystroke will - * {@link module:core/editor/editor~Editor#execute execute a command}. - * If a function, then it will be called with the - * {@link module:engine/view/observer/keyobserver~KeyEventData key event data} object and - * a `cancel()` helper to both `preventDefault()` and `stopPropagation()` of the event. - * @param options Additional options. - * @param options.priority The priority of the keystroke callback. The higher the priority value - * the sooner the callback will be executed. Keystrokes having the same priority - * are called in the order they were added. - */ - set(keystroke, callback, options = {}) { - if (typeof callback == 'string') { - const commandName = callback; - callback = (evtData, cancel) => { - this.editor.execute(commandName); - cancel(); - }; - } - super.set(keystroke, callback, options); - } -} - - -/***/ }), - -/***/ "./node_modules/@ckeditor/ckeditor5-core/src/editor/editor.js": -/*!********************************************************************!*\ - !*** ./node_modules/@ckeditor/ckeditor5-core/src/editor/editor.js ***! - \********************************************************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "default": () => (/* binding */ Editor) -/* harmony export */ }); -/* harmony import */ var _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @ckeditor/ckeditor5-utils */ "./node_modules/@ckeditor/ckeditor5-utils/src/index.js"); -/* harmony import */ var _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-engine */ "./node_modules/@ckeditor/ckeditor5-engine/src/index.js"); -/* harmony import */ var _context__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../context */ "./node_modules/@ckeditor/ckeditor5-core/src/context.js"); -/* harmony import */ var _plugincollection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../plugincollection */ "./node_modules/@ckeditor/ckeditor5-core/src/plugincollection.js"); -/* harmony import */ var _commandcollection__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../commandcollection */ "./node_modules/@ckeditor/ckeditor5-core/src/commandcollection.js"); -/* harmony import */ var _editingkeystrokehandler__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../editingkeystrokehandler */ "./node_modules/@ckeditor/ckeditor5-core/src/editingkeystrokehandler.js"); -/** - * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved. - * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license - */ -/** - * @module core/editor/editor - */ - - - - - - -/** - * The class representing a basic, generic editor. - * - * Check out the list of its subclasses to learn about specific editor implementations. - * - * All editor implementations (like {@link module:editor-classic/classiceditor~ClassicEditor} or - * {@link module:editor-inline/inlineeditor~InlineEditor}) should extend this class. They can add their - * own methods and properties. - * - * When you are implementing a plugin, this editor represents the API - * which your plugin can expect to get when using its {@link module:core/plugin~Plugin#editor} property. - * - * This API should be sufficient in order to implement the "editing" part of your feature - * (schema definition, conversion, commands, keystrokes, etc.). - * It does not define the editor UI, which is available only if - * the specific editor implements also the {@link ~Editor#ui} property - * (as most editor implementations do). - */ -class Editor extends (0,_ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.ObservableMixin)() { - /** - * Creates a new instance of the editor class. - * - * Usually, not to be used directly. See the static {@link module:core/editor/editor~Editor.create `create()`} method. - * - * @param config The editor configuration. - */ - constructor(config = {}) { - super(); - const constructor = this.constructor; - // Prefer the language passed as the argument to the constructor instead of the constructor's `defaultConfig`, if both are set. - const language = config.language || (constructor.defaultConfig && constructor.defaultConfig.language); - this._context = config.context || new _context__WEBPACK_IMPORTED_MODULE_2__["default"]({ language }); - this._context._addEditor(this, !config.context); - // Clone the plugins to make sure that the plugin array will not be shared - // between editors and make the watchdog feature work correctly. - const availablePlugins = Array.from(constructor.builtinPlugins || []); - this.config = new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.Config(config, constructor.defaultConfig); - this.config.define('plugins', availablePlugins); - this.config.define(this._context._getEditorConfig()); - this.plugins = new _plugincollection__WEBPACK_IMPORTED_MODULE_3__["default"](this, availablePlugins, this._context.plugins); - this.locale = this._context.locale; - this.t = this.locale.t; - this._readOnlyLocks = new Set(); - this.commands = new _commandcollection__WEBPACK_IMPORTED_MODULE_4__["default"](); - this.set('state', 'initializing'); - this.once('ready', () => (this.state = 'ready'), { priority: 'high' }); - this.once('destroy', () => (this.state = 'destroyed'), { priority: 'high' }); - this.model = new _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.Model(); - this.on('change:isReadOnly', () => { - this.model.document.isReadOnly = this.isReadOnly; - }); - const stylesProcessor = new _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.StylesProcessor(); - this.data = new _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.DataController(this.model, stylesProcessor); - this.editing = new _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.EditingController(this.model, stylesProcessor); - this.editing.view.document.bind('isReadOnly').to(this); - this.conversion = new _ckeditor_ckeditor5_engine__WEBPACK_IMPORTED_MODULE_1__.Conversion([this.editing.downcastDispatcher, this.data.downcastDispatcher], this.data.upcastDispatcher); - this.conversion.addAlias('dataDowncast', this.data.downcastDispatcher); - this.conversion.addAlias('editingDowncast', this.editing.downcastDispatcher); - this.keystrokes = new _editingkeystrokehandler__WEBPACK_IMPORTED_MODULE_5__["default"](this); - this.keystrokes.listenTo(this.editing.view.document); - } - /** - * Defines whether the editor is in the read-only mode. - * - * In read-only mode the editor {@link #commands commands} are disabled so it is not possible - * to modify the document by using them. Also, the editable element(s) become non-editable. - * - * In order to make the editor read-only, you need to call the {@link #enableReadOnlyMode} method: - * - * ```ts - * editor.enableReadOnlyMode( 'feature-id' ); - * ``` - * - * Later, to turn off the read-only mode, call {@link #disableReadOnlyMode}: - * - * ```ts - * editor.disableReadOnlyMode( 'feature-id' ); - * ``` - * - * @readonly - * @observable - */ - get isReadOnly() { - return this._readOnlyLocks.size > 0; - } - set isReadOnly(value) { - /** - * The {@link module:core/editor/editor~Editor#isReadOnly Editor#isReadOnly} property is read-only since version `34.0.0` - * and can be set only using {@link module:core/editor/editor~Editor#enableReadOnlyMode `Editor#enableReadOnlyMode( lockId )`} and - * {@link module:core/editor/editor~Editor#disableReadOnlyMode `Editor#disableReadOnlyMode( lockId )`}. - * - * Usage before version `34.0.0`: - * - * ```ts - * editor.isReadOnly = true; - * editor.isReadOnly = false; - * ``` - * - * Usage since version `34.0.0`: - * - * ```ts - * editor.enableReadOnlyMode( 'my-feature-id' ); - * editor.disableReadOnlyMode( 'my-feature-id' ); - * ``` - * - * @error editor-isreadonly-has-no-setter - */ - throw new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.CKEditorError('editor-isreadonly-has-no-setter'); - } - /** - * Turns on the read-only mode in the editor. - * - * Editor can be switched to or out of the read-only mode by many features, under various circumstances. The editor supports locking - * mechanism for the read-only mode. It enables easy control over the read-only mode when many features wants to turn it on or off at - * the same time, without conflicting with each other. It guarantees that you will not make the editor editable accidentally (which - * could lead to errors). - * - * Each read-only mode request is identified by a unique id (also called "lock"). If multiple plugins requested to turn on the - * read-only mode, then, the editor will become editable only after all these plugins turn the read-only mode off (using the same ids). - * - * Note, that you cannot force the editor to disable the read-only mode if other plugins set it. - * - * After the first `enableReadOnlyMode()` call, the {@link #isReadOnly `isReadOnly` property} will be set to `true`: - * - * ```ts - * editor.isReadOnly; // `false`. - * editor.enableReadOnlyMode( 'my-feature-id' ); - * editor.isReadOnly; // `true`. - * ``` - * - * You can turn off the read-only mode ("clear the lock") using the {@link #disableReadOnlyMode `disableReadOnlyMode()`} method: - * - * ```ts - * editor.enableReadOnlyMode( 'my-feature-id' ); - * // ... - * editor.disableReadOnlyMode( 'my-feature-id' ); - * editor.isReadOnly; // `false`. - * ``` - * - * All "locks" need to be removed to enable editing: - * - * ```ts - * editor.enableReadOnlyMode( 'my-feature-id' ); - * editor.enableReadOnlyMode( 'my-other-feature-id' ); - * // ... - * editor.disableReadOnlyMode( 'my-feature-id' ); - * editor.isReadOnly; // `true`. - * editor.disableReadOnlyMode( 'my-other-feature-id' ); - * editor.isReadOnly; // `false`. - * ``` - * - * @param lockId A unique ID for setting the editor to the read-only state. - */ - enableReadOnlyMode(lockId) { - if (typeof lockId !== 'string' && typeof lockId !== 'symbol') { - /** - * The lock ID is missing or it is not a string or symbol. - * - * @error editor-read-only-lock-id-invalid - */ - throw new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.CKEditorError('editor-read-only-lock-id-invalid', null, { lockId }); - } - if (this._readOnlyLocks.has(lockId)) { - return; - } - this._readOnlyLocks.add(lockId); - if (this._readOnlyLocks.size === 1) { - // Manually fire the `change:isReadOnly` event as only getter is provided. - this.fire('change:isReadOnly', 'isReadOnly', true, false); - } - } - /** - * Removes the read-only lock from the editor with given lock ID. - * - * When no lock is present on the editor anymore, then the {@link #isReadOnly `isReadOnly` property} will be set to `false`. - * - * @param lockId The lock ID for setting the editor to the read-only state. - */ - disableReadOnlyMode(lockId) { - if (typeof lockId !== 'string' && typeof lockId !== 'symbol') { - throw new _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.CKEditorError('editor-read-only-lock-id-invalid', null, { lockId }); - } - if (!this._readOnlyLocks.has(lockId)) { - return; - } - this._readOnlyLocks.delete(lockId); - if (this._readOnlyLocks.size === 0) { - // Manually fire the `change:isReadOnly` event as only getter is provided. - this.fire('change:isReadOnly', 'isReadOnly', false, true); - } - } - /** - * Loads and initializes plugins specified in the configuration. - * - * @returns A promise which resolves once the initialization is completed, providing an array of loaded plugins. - */ - initPlugins() { - const config = this.config; - const plugins = config.get('plugins'); - const removePlugins = config.get('removePlugins') || []; - const extraPlugins = config.get('extraPlugins') || []; - const substitutePlugins = config.get('substitutePlugins') || []; - return this.plugins.init(plugins.concat(extraPlugins), removePlugins, substitutePlugins); - } - /** - * Destroys the editor instance, releasing all resources used by it. - * - * **Note** The editor cannot be destroyed during the initialization phase so if it is called - * while the editor {@link #state is being initialized}, it will wait for the editor initialization before destroying it. - * - * @fires destroy - * @returns A promise that resolves once the editor instance is fully destroyed. - */ - destroy() { - let readyPromise = Promise.resolve(); - if (this.state == 'initializing') { - readyPromise = new Promise(resolve => this.once('ready', resolve)); - } - return readyPromise - .then(() => { - this.fire('destroy'); - this.stopListening(); - this.commands.destroy(); - }) - .then(() => this.plugins.destroy()) - .then(() => { - this.model.destroy(); - this.data.destroy(); - this.editing.destroy(); - this.keystrokes.destroy(); - }) - // Remove the editor from the context. - // When the context was created by this editor, the context will be destroyed. - .then(() => this._context._removeEditor(this)); - } - /** - * Executes the specified command with given parameters. - * - * Shorthand for: - * - * ```ts - * editor.commands.get( commandName ).execute( ... ); - * ``` - * - * @param commandName The name of the command to execute. - * @param commandParams Command parameters. - * @returns The value returned by the {@link module:core/commandcollection~CommandCollection#execute `commands.execute()`}. - */ - execute(commandName, ...commandParams) { - try { - return this.commands.execute(commandName, ...commandParams); - } - catch (err) { - // @if CK_DEBUG // throw err; - /* istanbul ignore next -- @preserve */ - _ckeditor_ckeditor5_utils__WEBPACK_IMPORTED_MODULE_0__.CKEditorError.rethrowUnexpectedError(err, this); - } - } - /** - * Focuses the editor. - * - * **Note** To explicitly focus the editing area of the editor, use the - * {@link module:engine/view/view~View#focus `editor.editing.view.focus()`} method of the editing view. - * - * Check out the {@glink framework/deep-dive/ui/focus-tracking#focus-in-the-editor-ui Focus in the editor UI} section - * of the {@glink framework/deep-dive/ui/focus-tracking Deep dive into focus tracking} guide to learn more. - */ - focus() { - this.editing.view.focus(); - } - /* istanbul ignore next -- @preserve */ - /** - * Creates and initializes a new editor instance. - * - * This is an abstract method. Every editor type needs to implement its own initialization logic. - * - * See the `create()` methods of the existing editor types to learn how to use them: - * - * * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`} - * * {@link module:editor-balloon/ballooneditor~BalloonEditor.create `BalloonEditor.create()`} - * * {@link module:editor-decoupled/decouplededitor~DecoupledEditor.create `DecoupledEditor.create()`} - * * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`} - */ - static create(...args) { - throw new Error('This is an abstract method.'); - } -} -/** - * This error is thrown when trying to pass a `