Merge pull request #4133 from dpalou/MOBILE-4587

Mobile 4587
main
Pau Ferrer Ocaña 2024-07-30 08:29:00 +02:00 committed by GitHub
commit 6dfb418b41
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 56 additions and 17 deletions

View File

@ -16,6 +16,8 @@ import { CoreDom } from '@singletons/dom';
import { CoreEventObserver } from '@singletons/events';
import { CoreLogger } from '@singletons/logger';
import { AddonModQuizDdImageOrTextQuestionData } from '../component/ddimageortext';
import { CoreLinkDirective } from '@directives/link';
import { ElementRef } from '@angular/core';
/**
* Class to make a question of ddimageortext type work.
@ -857,6 +859,12 @@ export class AddonQtypeDdImageOrTextQuestionDocStructure {
divDrag.setAttribute('dragitemno', String(dragItemNo));
divDrag.setAttribute('tabindex', '0');
Array.from(divDrag.querySelectorAll('a')).forEach((anchor) => {
const linkDir = new CoreLinkDirective(new ElementRef(anchor));
linkDir.capture = true;
linkDir.ngOnInit();
});
// Insert the new drag after the dragHome.
dragHome.parentElement?.insertBefore(divDrag, dragHome.nextSibling);

View File

@ -17,6 +17,7 @@
</ion-item>
<div class="fake-ion-item ion-text-wrap" [class.readonly]="question.readOnly" [hidden]="!question.loaded">
<core-format-text *ngIf="question.ddArea" [adaptImg]="false" [component]="component" [componentId]="componentId"
[text]="question.ddArea" [filter]="false" (afterRender)="ddAreaRendered()" />
[text]="question.ddArea" [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId"
(afterRender)="ddAreaRendered()" />
</div>
</div>

View File

@ -22,6 +22,8 @@ import { AddonQtypeDdMarkerGraphicsApi } from './graphics_api';
import { CoreUtils } from '@services/utils/utils';
import { CoreDirectivesRegistry } from '@singletons/directives-registry';
import { CoreExternalContentDirective } from '@directives/external-content';
import { CoreLinkDirective } from '@directives/link';
import { ElementRef } from '@angular/core';
/**
* Class to make a question of ddmarker type work.
@ -97,6 +99,8 @@ export class AddonQtypeDdMarkerQuestion {
drag.classList.remove('dragplaceholder'); // In case it has it.
dragHome.classList.add('dragplaceholder');
this.treatAnchors(drag);
// Insert the new drag after the dragHome.
dragHome.parentElement?.insertBefore(drag, dragHome.nextSibling);
if (!this.readOnly) {
@ -252,6 +256,7 @@ export class AddonQtypeDdMarkerQuestion {
// Marker text already exists. Update it or remove it if empty.
if (markerText !== '') {
existingMarkerText.innerHTML = markerText;
this.treatAnchors(existingMarkerText);
} else {
existingMarkerText.remove();
}
@ -262,6 +267,7 @@ export class AddonQtypeDdMarkerQuestion {
span.className = classNames;
span.innerHTML = markerText;
this.treatAnchors(span);
markerTexts.appendChild(span);
}
@ -896,6 +902,19 @@ export class AddonQtypeDdMarkerQuestion {
}
}
/**
* Treat anchors inside an element, adding the core-link directive.
*
* @param el Element to treat.
*/
protected treatAnchors(el: HTMLElement): void {
Array.from(el.querySelectorAll('a')).forEach((anchor) => {
const linkDir = new CoreLinkDirective(new ElementRef(anchor));
linkDir.capture = true;
linkDir.ngOnInit();
});
}
}
/**

View File

@ -17,6 +17,7 @@
</ion-item>
<div class="fake-ion-item ion-text-wrap" [hidden]="!question.loaded">
<core-format-text *ngIf="question.ddArea" [adaptImg]="false" [component]="component" [componentId]="componentId"
[text]="question.ddArea" [filter]="false" (afterRender)="ddAreaRendered()" />
[text]="question.ddArea" [contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId"
(afterRender)="ddAreaRendered()" />
</div>
</div>

View File

@ -17,6 +17,10 @@ core-format-text ::ng-deep {
user-select: none;
}
.d-none {
display: none;
}
.qtext {
margin-bottom: 0.5em;
display: block;

View File

@ -20,6 +20,8 @@ import { CoreEventObserver } from '@singletons/events';
import { CoreLogger } from '@singletons/logger';
import { AddonModQuizDdwtosQuestionData } from '../component/ddwtos';
import { CoreWait } from '@singletons/wait';
import { CoreLinkDirective } from '@directives/link';
import { ElementRef } from '@angular/core';
/**
* Class to make a question of ddwtos type work.
@ -69,6 +71,13 @@ export class AddonQtypeDdwtosQuestion {
drag.style.visibility = 'visible';
drag.style.position = 'absolute';
Array.from(drag.querySelectorAll('a')).forEach((anchor) => {
// Cloning the item doesn't clone its directives. Add core-link to the anchors.
const linkDir = new CoreLinkDirective(new ElementRef(anchor));
linkDir.capture = true;
linkDir.ngOnInit();
});
const container = this.container.querySelector(this.selectors.dragContainer());
container?.appendChild(drag);

View File

@ -15,9 +15,8 @@
[contextInstanceId]="contextInstanceId" [courseId]="courseId" #questiontext (afterRender)="textRendered()" />
<core-format-text *ngIf="question.answers" [component]="component" [componentId]="componentId" [text]="question.answers"
[filter]="false" (afterRender)="answersRendered()" />
<div class="drags"></div>
[contextLevel]="contextLevel" [contextInstanceId]="contextInstanceId" [courseId]="courseId"
(afterRender)="answersRendered()" />
</div>
</div>
</div>

View File

@ -23,7 +23,6 @@ core-format-text ::ng-deep, .drags ::ng-deep {
}
.draghome {
margin-bottom: 1em;
max-width: calc(100%);
}
@ -47,6 +46,10 @@ core-format-text ::ng-deep, .drags ::ng-deep {
white-space: normal;
overflow: visible;
word-wrap: break-word;
margin-bottom: 1em;
border-radius: 5px;
line-height: 25px;
cursor: var(--cursor);
}
.draghome, .drag.unplaced{
border: 1px solid var(--core-dd-question-border);
@ -56,9 +59,6 @@ core-format-text ::ng-deep, .drags ::ng-deep {
}
.drag {
z-index: 2;
border-radius: 5px;
line-height: 25px;
cursor: var(--cursor);
}
.drag.selected,
.drop.selected {

View File

@ -69,7 +69,9 @@ export class AddonQtypeDdwtosComponent extends CoreQuestionBaseComponent<AddonMo
}
this.question.readOnly = answerContainer.classList.contains('readonly');
this.question.answers = answerContainer.outerHTML;
// Add the drags container inside the answers so it's rendered inside core-format-text,
// otherwise some styles could be different between the drag homes and the draggables.
this.question.answers = answerContainer.outerHTML + '<div class="drags"></div>';
// Get the inputs where the answers will be stored and add them to the question text.
const inputEls = Array.from(

View File

@ -27,7 +27,6 @@ import {
Inject,
ChangeDetectorRef,
} from '@angular/core';
import { IonContent } from '@ionic/angular';
import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
@ -104,7 +103,6 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncDirec
constructor(
element: ElementRef,
@Optional() protected content: IonContent,
protected viewContainerRef: ViewContainerRef,
@Optional() @Inject(CORE_REFRESH_CONTEXT) protected refreshContext?: CoreRefreshContext,
) {
@ -503,8 +501,8 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncDirec
return;
}
// Angular 2 doesn't let adding directives dynamically. Create the CoreLinkDirective manually.
const linkDir = new CoreLinkDirective(new ElementRef(anchor), this.content);
// Angular doesn't let adding directives dynamically. Create the CoreLinkDirective manually.
const linkDir = new CoreLinkDirective(new ElementRef(anchor));
linkDir.capture = this.captureLinks ?? true;
linkDir.inApp = this.openLinksInApp;
linkDir.ngOnInit();

View File

@ -12,9 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Directive, Input, OnInit, ElementRef, Optional, SecurityContext } from '@angular/core';
import { Directive, Input, OnInit, ElementRef, SecurityContext } from '@angular/core';
import { SafeUrl } from '@angular/platform-browser';
import { IonContent } from '@ionic/angular';
import { CoreFileHelper } from '@services/file-helper';
import { CoreSites } from '@services/sites';
@ -47,7 +46,6 @@ export class CoreLinkDirective implements OnInit {
constructor(
element: ElementRef,
@Optional() protected content: IonContent,
) {
this.element = element.nativeElement;
}