Merge pull request #2971 from dpalou/MOBILE-3726
MOBILE-3726 core: Display warning modal before open browser
This commit is contained in:
		
						commit
						71dae09df6
					
				| @ -1578,6 +1578,7 @@ | |||||||
|   "core.dismiss": "local_moodlemobileapp", |   "core.dismiss": "local_moodlemobileapp", | ||||||
|   "core.displayoptions": "atto_media", |   "core.displayoptions": "atto_media", | ||||||
|   "core.done": "survey", |   "core.done": "survey", | ||||||
|  |   "core.dontshowagain": "local_moodlemobileapp", | ||||||
|   "core.download": "moodle", |   "core.download": "moodle", | ||||||
|   "core.downloaded": "local_moodlemobileapp", |   "core.downloaded": "local_moodlemobileapp", | ||||||
|   "core.downloadfile": "moodle", |   "core.downloadfile": "moodle", | ||||||
| @ -2257,6 +2258,7 @@ | |||||||
|   "core.viewembeddedcontent": "local_moodlemobileapp", |   "core.viewembeddedcontent": "local_moodlemobileapp", | ||||||
|   "core.viewprofile": "moodle", |   "core.viewprofile": "moodle", | ||||||
|   "core.warningofflinedatadeleted": "local_moodlemobileapp", |   "core.warningofflinedatadeleted": "local_moodlemobileapp", | ||||||
|  |   "core.warnopeninbrowser": "local_moodlemobileapp", | ||||||
|   "core.whatisyourage": "moodle", |   "core.whatisyourage": "moodle", | ||||||
|   "core.wheredoyoulive": "moodle", |   "core.wheredoyoulive": "moodle", | ||||||
|   "core.whoissiteadmin": "local_moodlemobileapp", |   "core.whoissiteadmin": "local_moodlemobileapp", | ||||||
|  | |||||||
| @ -53,7 +53,9 @@ | |||||||
|                 <ion-item class="ion-text-wrap" *ngIf="badge.issuercontact"> |                 <ion-item class="ion-text-wrap" *ngIf="badge.issuercontact"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <h2>{{ 'addon.badges.contact' | translate}}</h2> |                         <h2>{{ 'addon.badges.contact' | translate}}</h2> | ||||||
|                         <p><a href="mailto:{{badge.issuercontact}}" core-link auto-login="no"> {{ badge.issuercontact }} </a></p> |                         <p><a href="mailto:{{badge.issuercontact}}" core-link auto-login="no" [showBrowserWarning]="false"> | ||||||
|  |                             {{ badge.issuercontact }} | ||||||
|  |                         </a></p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|             </ion-item-group> |             </ion-item-group> | ||||||
| @ -97,7 +99,9 @@ | |||||||
|                 <ion-item class="ion-text-wrap" *ngIf="badge.imageauthoremail"> |                 <ion-item class="ion-text-wrap" *ngIf="badge.imageauthoremail"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <h2>{{ 'addon.badges.imageauthoremail' | translate}}</h2> |                         <h2>{{ 'addon.badges.imageauthoremail' | translate}}</h2> | ||||||
|                         <p><a href="mailto:{{badge.imageauthoremail}}" core-link auto-login="no"> {{ badge.imageauthoremail }} </a></p> |                         <p><a href="mailto:{{badge.imageauthoremail}}" core-link auto-login="no" [showBrowserWarning]="false"> | ||||||
|  |                             {{ badge.imageauthoremail }} | ||||||
|  |                         </a></p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                 </ion-item> |                 </ion-item> | ||||||
|                 <ion-item class="ion-text-wrap" *ngIf="badge.imageauthorurl"> |                 <ion-item class="ion-text-wrap" *ngIf="badge.imageauthorurl"> | ||||||
| @ -165,7 +169,8 @@ | |||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <h2>{{ 'addon.badges.issueremail' | translate}}</h2> |                         <h2>{{ 'addon.badges.issueremail' | translate}}</h2> | ||||||
|                         <p> |                         <p> | ||||||
|                             <a href="mailto:{{badge.endorsement.issueremail}}" core-link auto-login="no"> |                             <a href="mailto:{{badge.endorsement.issueremail}}" core-link auto-login="no" | ||||||
|  |                                 [showBrowserWarning]="false"> | ||||||
|                                 {{ badge.endorsement.issueremail }} |                                 {{ badge.endorsement.issueremail }} | ||||||
|                             </a> |                             </a> | ||||||
|                         </p> |                         </p> | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="assign && (description || (assign.introattachments && assign.introattachments.length))" |         <core-context-menu-item *ngIf="assign && (description || (assign.introattachments && assign.introattachments.length))" | ||||||
|             [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" |             [priority]="800" [content]="'core.moduleintro' | translate" (action)="expandDescription()" | ||||||
|  | |||||||
| @ -353,7 +353,7 @@ | |||||||
|                         <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon> |                         <ion-icon name="fas-exclamation-triangle" slot="start" aria-hidden="true"></ion-icon> | ||||||
|                         <ion-label> |                         <ion-label> | ||||||
|                             <p>{{ 'addon.mod_assign.cannotgradefromapp' | translate }}</p> |                             <p>{{ 'addon.mod_assign.cannotgradefromapp' | translate }}</p> | ||||||
|                             <ion-button expand="block" *ngIf="gradeUrl" [href]="gradeUrl" core-link > |                             <ion-button expand="block" *ngIf="gradeUrl" [href]="gradeUrl" core-link [showBrowserWarning]="false"> | ||||||
|                                 {{ 'core.openinbrowser' | translate }} |                                 {{ 'core.openinbrowser' | translate }} | ||||||
|                                 <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon> |                                 <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon> | ||||||
|                             </ion-button> |                             </ion-button> | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ | |||||||
|     </ion-button> |     </ion-button> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"></core-context-menu-item> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"></core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"></core-context-menu-item> |             (action)="expandDescription()" iconAction="fas-arrow-right"></core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ | |||||||
|     </ion-button> |     </ion-button> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt">> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|  | |||||||
| @ -17,7 +17,8 @@ | |||||||
|             <p  class="item-heading">{{ 'core.numwords' | translate: {'$a': wordCount} }}</p> |             <p  class="item-heading">{{ 'core.numwords' | translate: {'$a': wordCount} }}</p> | ||||||
|         </ion-label> |         </ion-label> | ||||||
|     </ion-item> |     </ion-item> | ||||||
|     <ion-item class="ion-text-wrap" [href]="url" *ngIf="url" core-link capture="false" button detail="false"> |     <ion-item class="ion-text-wrap" [href]="url" *ngIf="url" core-link capture="false" button detail="false" | ||||||
|  |         [showBrowserWarning]="false"> | ||||||
|         <ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon> |         <ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon> | ||||||
|         <ion-label> |         <ion-label> | ||||||
|             <p  class="item-heading">{{ 'core.openinbrowser' | translate }}</p> |             <p  class="item-heading">{{ 'core.openinbrowser' | translate }}</p> | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ | |||||||
| 
 | 
 | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ | |||||||
|             iconAction="stats-chart"> |             iconAction="stats-chart"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ | |||||||
|     </ion-button> |     </ion-button> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|  | |||||||
| @ -74,7 +74,7 @@ export class AddonModLtiHelperProvider { | |||||||
|                     module, |                     module, | ||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
|                 return site.openInBrowserWithAutoLogin(module.url!); |                 return site.openInBrowserWithAutoLogin(module.url || ''); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // Open in app.
 |             // Open in app.
 | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
| @ -218,7 +218,8 @@ | |||||||
| 
 | 
 | ||||||
|             <!-- Button to open in browser if it cannot be attempted in the app. --> |             <!-- Button to open in browser if it cannot be attempted in the app. --> | ||||||
|             <ion-button class="ion-margin" *ngIf="!buttonText && ((!hasSupportedQuestions && unsupportedQuestions.length) || |             <ion-button class="ion-margin" *ngIf="!buttonText && ((!hasSupportedQuestions && unsupportedQuestions.length) || | ||||||
|                 unsupportedRules.length || behaviourSupported === false)" expand="block" [href]="externalUrl" core-link> |                 unsupportedRules.length || behaviourSupported === false)" expand="block" [href]="externalUrl" core-link | ||||||
|  |                 [showBrowserWarning]="false"> | ||||||
|                 {{ 'core.openinbrowser' | translate }} |                 {{ 'core.openinbrowser' | translate }} | ||||||
|                 <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon> | ||||||
|             </ion-button> |             </ion-button> | ||||||
|  | |||||||
| @ -165,7 +165,8 @@ | |||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
| 
 | 
 | ||||||
|             <ion-button *ngIf="preventSubmitMessages.length" expand="block" [href]="moduleUrl" core-link> |             <ion-button *ngIf="preventSubmitMessages.length" expand="block" [href]="moduleUrl" core-link | ||||||
|  |                 [showBrowserWarning]="false"> | ||||||
|                 {{ 'core.openinbrowser' | translate }} |                 {{ 'core.openinbrowser' | translate }} | ||||||
|                 <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon> | ||||||
|             </ion-button> |             </ion-button> | ||||||
| @ -182,7 +183,7 @@ | |||||||
|             <ion-item class="ion-text-wrap"> |             <ion-item class="ion-text-wrap"> | ||||||
|                 <ion-label>{{ 'addon.mod_quiz.errorparsequestions' | translate }}</ion-label> |                 <ion-label>{{ 'addon.mod_quiz.errorparsequestions' | translate }}</ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-button expand="block" class="ion-margin" [href]="moduleUrl" core-link> |             <ion-button expand="block" class="ion-margin" [href]="moduleUrl" core-link [showBrowserWarning]="false"> | ||||||
|                 {{ 'core.openinbrowser' | translate }} |                 {{ 'core.openinbrowser' | translate }} | ||||||
|                 <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon> | ||||||
|             </ion-button> |             </ion-button> | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"></core-context-menu-item> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"></core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"></core-context-menu-item> |             (action)="expandDescription()" iconAction="fas-arrow-right"></core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" | ||||||
|  | |||||||
| @ -188,7 +188,7 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // The resource cannot be downloaded, open the activity in browser.
 |         // The resource cannot be downloaded, open the activity in browser.
 | ||||||
|         await CoreSites.getCurrentSite()?.openInBrowserWithAutoLoginIfSameSite(this.module.url!); |         await CoreSites.getCurrentSite()?.openInBrowserWithAutoLoginIfSameSite(this.module.url || ''); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
| @ -185,7 +185,7 @@ | |||||||
|                     <p class="text-danger">{{ errorMessage | translate }}</p> |                     <p class="text-danger">{{ errorMessage | translate }}</p> | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-button class="ion-margin ion-text-wrap" expand="block" [href]="externalUrl" core-link> |             <ion-button class="ion-margin ion-text-wrap" expand="block" [href]="externalUrl" core-link [showBrowserWarning]="false"> | ||||||
|                 {{ 'core.openinbrowser' | translate }} |                 {{ 'core.openinbrowser' | translate }} | ||||||
|                 <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon> | ||||||
|             </ion-button> |             </ion-button> | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"></core-context-menu-item> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"></core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"></core-context-menu-item> |             (action)="expandDescription()" iconAction="fas-arrow-right"></core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" |         <core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}" | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ | |||||||
| 
 | 
 | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| <core-navbar-buttons slot="end"> | <core-navbar-buttons slot="end"> | ||||||
|     <core-context-menu> |     <core-context-menu> | ||||||
|         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" |         <core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate" | ||||||
|             [href]="externalUrl" iconAction="fas-external-link-alt"> |             [href]="externalUrl" iconAction="fas-external-link-alt" [showBrowserWarning]="false"> | ||||||
|         </core-context-menu-item> |         </core-context-menu-item> | ||||||
|         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" |         <core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate" | ||||||
|             (action)="expandDescription()" iconAction="fas-arrow-right"> |             (action)="expandDescription()" iconAction="fas-arrow-right"> | ||||||
|  | |||||||
| @ -355,7 +355,7 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity | |||||||
|      * |      * | ||||||
|      * @param task Task to be done. |      * @param task Task to be done. | ||||||
|      */ |      */ | ||||||
|     runTask(task: AddonModWorkshopPhaseTaskData): void { |     async runTask(task: AddonModWorkshopPhaseTaskData): Promise<void> { | ||||||
|         if (task.code == 'submit') { |         if (task.code == 'submit') { | ||||||
|             this.gotoSubmit(); |             this.gotoSubmit(); | ||||||
|         } else if (task.link) { |         } else if (task.link) { | ||||||
|  | |||||||
| @ -57,7 +57,7 @@ export class AddonModWorkshopPhaseInfoComponent implements OnInit { | |||||||
|      * |      * | ||||||
|      * @param task Task to be done. |      * @param task Task to be done. | ||||||
|      */ |      */ | ||||||
|     runTask(task: AddonModWorkshopPhaseTaskData): void { |     async runTask(task: AddonModWorkshopPhaseTaskData): Promise<void> { | ||||||
|         if (task.code == 'submit') { |         if (task.code == 'submit') { | ||||||
|             // This will close the modal and go to the submit.
 |             // This will close the modal and go to the submit.
 | ||||||
|             ModalController.dismiss(true); |             ModalController.dismiss(true); | ||||||
|  | |||||||
| @ -104,17 +104,20 @@ export class AddonNotificationsPushClickHandlerService implements CorePushNotifi | |||||||
|                 case 'browser': |                 case 'browser': | ||||||
|                     return CoreUtils.openInBrowser(url); |                     return CoreUtils.openInBrowser(url); | ||||||
| 
 | 
 | ||||||
|                 default: |                 default: { | ||||||
|                     if (CoreContentLinksHelper.handleLink(url, undefined, undefined, true)) { |                     const treated = await CoreContentLinksHelper.handleLink(url, undefined, undefined, true); | ||||||
|  |                     if (treated) { | ||||||
|                         // Link treated, stop.
 |                         // Link treated, stop.
 | ||||||
|                         return; |                         return; | ||||||
|                     } |                     } | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // No appurl or cannot be handled by the app. Try to handle the contexturl now.
 |         // No appurl or cannot be handled by the app. Try to handle the contexturl now.
 | ||||||
|         if (notification.contexturl) { |         if (notification.contexturl) { | ||||||
|             if (CoreContentLinksHelper.handleLink(notification.contexturl)) { |             const treated = await CoreContentLinksHelper.handleLink(notification.contexturl); | ||||||
|  |             if (treated) { | ||||||
|                 // Link treated, stop.
 |                 // Link treated, stop.
 | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -125,7 +125,7 @@ export class AppComponent implements OnInit, AfterViewInit { | |||||||
|                 const urlScheme = CoreUrlUtils.getUrlProtocol(url); |                 const urlScheme = CoreUrlUtils.getUrlProtocol(url); | ||||||
|                 if (urlScheme && urlScheme !== 'file' && urlScheme !== 'cdvfile') { |                 if (urlScheme && urlScheme !== 'file' && urlScheme !== 'cdvfile') { | ||||||
|                     // Open in browser should launch the right app if found and do nothing if not found.
 |                     // Open in browser should launch the right app if found and do nothing if not found.
 | ||||||
|                     CoreUtils.openInBrowser(url); |                     CoreUtils.openInBrowser(url, { showBrowserWarning: false }); | ||||||
| 
 | 
 | ||||||
|                     // At this point the InAppBrowser is showing a "Webpage not available" error message.
 |                     // At this point the InAppBrowser is showing a "Webpage not available" error message.
 | ||||||
|                     // Try to navigate to last loaded URL so this error message isn't found.
 |                     // Try to navigate to last loaded URL so this error message isn't found.
 | ||||||
|  | |||||||
| @ -32,7 +32,7 @@ import { CoreDomUtils } from '@services/utils/dom'; | |||||||
| import { CoreTextUtils } from '@services/utils/text'; | import { CoreTextUtils } from '@services/utils/text'; | ||||||
| import { CoreTimeUtils } from '@services/utils/time'; | import { CoreTimeUtils } from '@services/utils/time'; | ||||||
| import { CoreUrlUtils, CoreUrlParams } from '@services/utils/url'; | import { CoreUrlUtils, CoreUrlParams } from '@services/utils/url'; | ||||||
| import { CoreUtils, PromiseDefer } from '@services/utils/utils'; | import { CoreUtils, CoreUtilsOpenInBrowserOptions, PromiseDefer } from '@services/utils/utils'; | ||||||
| import { CoreConstants } from '@/core/constants'; | import { CoreConstants } from '@/core/constants'; | ||||||
| import { SQLiteDB } from '@classes/sqlitedb'; | import { SQLiteDB } from '@classes/sqlitedb'; | ||||||
| import { CoreError } from '@classes/errors/error'; | import { CoreError } from '@classes/errors/error'; | ||||||
| @ -1381,10 +1381,15 @@ export class CoreSite { | |||||||
|      * |      * | ||||||
|      * @param url The URL to open. |      * @param url The URL to open. | ||||||
|      * @param alertMessage If defined, an alert will be shown before opening the browser. |      * @param alertMessage If defined, an alert will be shown before opening the browser. | ||||||
|  |      * @param options Other options. | ||||||
|      * @return Promise resolved when done, rejected otherwise. |      * @return Promise resolved when done, rejected otherwise. | ||||||
|      */ |      */ | ||||||
|     async openInBrowserWithAutoLogin(url: string, alertMessage?: string): Promise<void> { |     async openInBrowserWithAutoLogin( | ||||||
|         await this.openWithAutoLogin(false, url, undefined, alertMessage); |         url: string, | ||||||
|  |         alertMessage?: string, | ||||||
|  |         options: CoreUtilsOpenInBrowserOptions = {}, | ||||||
|  |     ): Promise<void> { | ||||||
|  |         await this.openWithAutoLogin(false, url, options, alertMessage); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -1392,10 +1397,15 @@ export class CoreSite { | |||||||
|      * |      * | ||||||
|      * @param url The URL to open. |      * @param url The URL to open. | ||||||
|      * @param alertMessage If defined, an alert will be shown before opening the browser. |      * @param alertMessage If defined, an alert will be shown before opening the browser. | ||||||
|  |      * @param options Other options. | ||||||
|      * @return Promise resolved when done, rejected otherwise. |      * @return Promise resolved when done, rejected otherwise. | ||||||
|      */ |      */ | ||||||
|     async openInBrowserWithAutoLoginIfSameSite(url: string, alertMessage?: string): Promise<void> { |     async openInBrowserWithAutoLoginIfSameSite( | ||||||
|         await this.openWithAutoLoginIfSameSite(false, url, undefined, alertMessage); |         url: string, | ||||||
|  |         alertMessage?: string, | ||||||
|  |         options: CoreUtilsOpenInBrowserOptions = {}, | ||||||
|  |     ): Promise<void> { | ||||||
|  |         await this.openWithAutoLoginIfSameSite(false, url, options, alertMessage); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -1442,7 +1452,7 @@ export class CoreSite { | |||||||
|     async openWithAutoLogin( |     async openWithAutoLogin( | ||||||
|         inApp: boolean, |         inApp: boolean, | ||||||
|         url: string, |         url: string, | ||||||
|         options?: InAppBrowserOptions, |         options: InAppBrowserOptions & CoreUtilsOpenInBrowserOptions = {}, | ||||||
|         alertMessage?: string, |         alertMessage?: string, | ||||||
|     ): Promise<InAppBrowserObject | void> { |     ): Promise<InAppBrowserObject | void> { | ||||||
|         // Get the URL to open.
 |         // Get the URL to open.
 | ||||||
| @ -1458,13 +1468,14 @@ export class CoreSite { | |||||||
|             ); |             ); | ||||||
| 
 | 
 | ||||||
|             await alert.onDidDismiss(); |             await alert.onDidDismiss(); | ||||||
|  |             options.showBrowserWarning = false; // A warning already shown, no need to show another.
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Open the URL.
 |         // Open the URL.
 | ||||||
|         if (inApp) { |         if (inApp) { | ||||||
|             return CoreUtils.openInApp(url, options); |             return CoreUtils.openInApp(url, options); | ||||||
|         } else { |         } else { | ||||||
|             return CoreUtils.openInBrowser(url); |             return CoreUtils.openInBrowser(url, options); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -1480,7 +1491,7 @@ export class CoreSite { | |||||||
|     async openWithAutoLoginIfSameSite( |     async openWithAutoLoginIfSameSite( | ||||||
|         inApp: boolean, |         inApp: boolean, | ||||||
|         url: string, |         url: string, | ||||||
|         options?: InAppBrowserOptions, |         options: InAppBrowserOptions & CoreUtilsOpenInBrowserOptions = {}, | ||||||
|         alertMessage?: string, |         alertMessage?: string, | ||||||
|     ): Promise<InAppBrowserObject | void> { |     ): Promise<InAppBrowserObject | void> { | ||||||
|         if (this.containsUrl(url)) { |         if (this.containsUrl(url)) { | ||||||
| @ -1489,7 +1500,7 @@ export class CoreSite { | |||||||
|             if (inApp) { |             if (inApp) { | ||||||
|                 return Promise.resolve(CoreUtils.openInApp(url, options)); |                 return Promise.resolve(CoreUtils.openInApp(url, options)); | ||||||
|             } else { |             } else { | ||||||
|                 CoreUtils.openInBrowser(url); |                 CoreUtils.openInBrowser(url, options); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -51,6 +51,7 @@ export class CoreContextMenuItemComponent implements OnInit, OnDestroy, OnChange | |||||||
|     @Input() badgeClass?: number; // A class to set in the badge.
 |     @Input() badgeClass?: number; // A class to set in the badge.
 | ||||||
|     @Input() badgeA11yText?: string; // Description for the badge, if needed.
 |     @Input() badgeA11yText?: string; // Description for the badge, if needed.
 | ||||||
|     @Input() hidden?: boolean; // Whether the item should be hidden.
 |     @Input() hidden?: boolean; // Whether the item should be hidden.
 | ||||||
|  |     @Input() showBrowserWarning = true; // Whether to show a warning before opening browser (for links). Defaults to true.
 | ||||||
|     @Output() action?: EventEmitter<() => void>; // Will emit an event when the item clicked.
 |     @Output() action?: EventEmitter<() => void>; // Will emit an event when the item clicked.
 | ||||||
|     @Output() onClosed?: EventEmitter<() => void>; // Will emit an event when the popover is closed because the item was clicked.
 |     @Output() onClosed?: EventEmitter<() => void>; // Will emit an event when the popover is closed because the item was clicked.
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,7 +4,8 @@ | |||||||
|     </ion-list-header> |     </ion-list-header> | ||||||
|     <ion-item class="ion-text-wrap" *ngFor="let item of items" core-link [capture]="item.captureLink" [autoLogin]="item.autoLogin" |     <ion-item class="ion-text-wrap" *ngFor="let item of items" core-link [capture]="item.captureLink" [autoLogin]="item.autoLogin" | ||||||
|         [href]="item.href" (click)="itemClicked($event, item)" [attr.aria-label]="item.ariaAction" [hidden]="item.hidden" |         [href]="item.href" (click)="itemClicked($event, item)" [attr.aria-label]="item.ariaAction" [hidden]="item.hidden" | ||||||
|         [detail]="(item.href && !item.iconAction) || null" role="menuitem" [button]="(item.href && !item.iconAction)"> |         [detail]="(item.href && !item.iconAction) || null" role="menuitem" [button]="(item.href && !item.iconAction)" | ||||||
|  |         [showBrowserWarning]="item.showBrowserWarning"> | ||||||
|         <ion-icon *ngIf="item.iconDescription" [name]="item.iconDescription" aria-hidden="true" slot="start"> |         <ion-icon *ngIf="item.iconDescription" [name]="item.iconDescription" aria-hidden="true" slot="start"> | ||||||
|         </ion-icon> |         </ion-icon> | ||||||
|         <ion-label> |         <ion-label> | ||||||
|  | |||||||
| @ -63,6 +63,7 @@ export class CoreConstants { | |||||||
|     static readonly SETTINGS_ZOOM_LEVEL = 'CoreSettingsZoomLevel'; |     static readonly SETTINGS_ZOOM_LEVEL = 'CoreSettingsZoomLevel'; | ||||||
|     static readonly SETTINGS_COLOR_SCHEME = 'CoreSettingsColorScheme'; |     static readonly SETTINGS_COLOR_SCHEME = 'CoreSettingsColorScheme'; | ||||||
|     static readonly SETTINGS_ANALYTICS_ENABLED = 'CoreSettingsAnalyticsEnabled'; |     static readonly SETTINGS_ANALYTICS_ENABLED = 'CoreSettingsAnalyticsEnabled'; | ||||||
|  |     static readonly SETTINGS_DONT_SHOW_EXTERNAL_LINK_WARN = 'CoreSettingsDontShowExtLinkWarn'; | ||||||
| 
 | 
 | ||||||
|     // WS constants.
 |     // WS constants.
 | ||||||
|     static readonly WS_TIMEOUT = 30000; // Timeout when not in WiFi.
 |     static readonly WS_TIMEOUT = 30000; // Timeout when not in WiFi.
 | ||||||
|  | |||||||
| @ -43,6 +43,7 @@ export class CoreLinkDirective implements OnInit { | |||||||
|        "no" -> Never auto-login. |        "no" -> Never auto-login. | ||||||
|        "check" -> Auto-login only if it points to the current site. Default value. */ |        "check" -> Auto-login only if it points to the current site. Default value. */ | ||||||
|     @Input() autoLogin = 'check'; |     @Input() autoLogin = 'check'; | ||||||
|  |     @Input() showBrowserWarning = true; // Whether to show a warning before opening browser. Defaults to true.
 | ||||||
| 
 | 
 | ||||||
|     protected element: Element; |     protected element: Element; | ||||||
| 
 | 
 | ||||||
| @ -199,33 +200,35 @@ export class CoreLinkDirective implements OnInit { | |||||||
|             if (this.inApp) { |             if (this.inApp) { | ||||||
|                 CoreUtils.openInApp(href); |                 CoreUtils.openInApp(href); | ||||||
|             } else { |             } else { | ||||||
|                 CoreUtils.openInBrowser(href); |                 CoreUtils.openInBrowser(href, { showBrowserWarning: this.showBrowserWarning }); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         const currentSite = CoreSites.getRequiredCurrentSite(); | ||||||
|  | 
 | ||||||
|         // Check if URL does not have any protocol, so it's a relative URL.
 |         // Check if URL does not have any protocol, so it's a relative URL.
 | ||||||
|         if (!CoreUrlUtils.isAbsoluteURL(href)) { |         if (!CoreUrlUtils.isAbsoluteURL(href)) { | ||||||
|             // Add the site URL at the begining.
 |             // Add the site URL at the begining.
 | ||||||
|             if (href.charAt(0) == '/') { |             if (href.charAt(0) == '/') { | ||||||
|                 href = CoreSites.getCurrentSite()!.getURL() + href; |                 href = currentSite.getURL() + href; | ||||||
|             } else { |             } else { | ||||||
|                 href = CoreSites.getCurrentSite()!.getURL() + '/' + href; |                 href = currentSite.getURL() + '/' + href; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (this.autoLogin == 'yes') { |         if (this.autoLogin == 'yes') { | ||||||
|             if (this.inApp) { |             if (this.inApp) { | ||||||
|                 await CoreSites.getCurrentSite()!.openInAppWithAutoLogin(href); |                 await currentSite.openInAppWithAutoLogin(href); | ||||||
|             } else { |             } else { | ||||||
|                 await CoreSites.getCurrentSite()!.openInBrowserWithAutoLogin(href); |                 await currentSite.openInBrowserWithAutoLogin(href, undefined, { showBrowserWarning: this.showBrowserWarning }); | ||||||
|             } |             } | ||||||
|         } else if (this.autoLogin == 'no') { |         } else if (this.autoLogin == 'no') { | ||||||
|             if (this.inApp) { |             if (this.inApp) { | ||||||
|                 CoreUtils.openInApp(href); |                 CoreUtils.openInApp(href); | ||||||
|             } else { |             } else { | ||||||
|                 CoreUtils.openInBrowser(href); |                 CoreUtils.openInBrowser(href, { showBrowserWarning: this.showBrowserWarning }); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             // Priority order is: core-link inApp attribute > forceOpenLinksIn setting > data-open-in HTML attribute.
 |             // Priority order is: core-link inApp attribute > forceOpenLinksIn setting > data-open-in HTML attribute.
 | ||||||
| @ -239,9 +242,13 @@ export class CoreLinkDirective implements OnInit { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (openInApp) { |             if (openInApp) { | ||||||
|                 await CoreSites.getCurrentSite()!.openInAppWithAutoLoginIfSameSite(href); |                 await currentSite.openInAppWithAutoLoginIfSameSite(href); | ||||||
|             } else { |             } else { | ||||||
|                 await CoreSites.getCurrentSite()!.openInBrowserWithAutoLoginIfSameSite(href); |                 await currentSite.openInBrowserWithAutoLoginIfSameSite( | ||||||
|  |                     href, | ||||||
|  |                     undefined, | ||||||
|  |                     { showBrowserWarning: this.showBrowserWarning }, | ||||||
|  |                 ); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ | |||||||
| 
 | 
 | ||||||
|     <div *ngIf="module && module.url"> |     <div *ngIf="module && module.url"> | ||||||
|         <p><strong>{{ 'core.course.useactivityonbrowser' | translate }}</strong></p> |         <p><strong>{{ 'core.course.useactivityonbrowser' | translate }}</strong></p> | ||||||
|         <ion-button expand="block" [href]="module.url" core-link> |         <ion-button expand="block" [href]="module.url" core-link [showBrowserWarning]="false"> | ||||||
|             {{ 'core.openinbrowser' | translate }} |             {{ 'core.openinbrowser' | translate }} | ||||||
|             <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon> |             <ion-icon name="fas-external-link-alt" slot="end" aria-hidden="true"></ion-icon> | ||||||
|         </ion-button> |         </ion-button> | ||||||
|  | |||||||
| @ -123,7 +123,8 @@ | |||||||
|                 <ion-icon name="fas-briefcase" slot="start" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-briefcase" slot="start" aria-hidden="true"></ion-icon> | ||||||
|                 <ion-label><h2>{{ 'core.course.contents' | translate }}</h2></ion-label> |                 <ion-label><h2>{{ 'core.course.contents' | translate }}</h2></ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-item [href]="courseUrl" core-link [attr.aria-label]="course.fullname" button detail="false"> |             <ion-item [href]="courseUrl" core-link [attr.aria-label]="course.fullname" button detail="false" | ||||||
|  |                 [showBrowserWarning]="false"> | ||||||
|                 <ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon> |                 <ion-icon name="fas-external-link-alt" slot="start" aria-hidden="true"></ion-icon> | ||||||
|                 <ion-label><h2>{{ 'core.openinbrowser' | translate }}</h2></ion-label> |                 <ion-label><h2>{{ 'core.openinbrowser' | translate }}</h2></ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|  | |||||||
| @ -222,7 +222,7 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler | |||||||
|                 try { |                 try { | ||||||
|                     await CoreDomUtils.showConfirm(body); |                     await CoreDomUtils.showConfirm(body); | ||||||
| 
 | 
 | ||||||
|                     CoreSites.getCurrentSite()?.openInBrowserWithAutoLogin(url); |                     CoreSites.getCurrentSite()?.openInBrowserWithAutoLogin(url, undefined, { showBrowserWarning: false }); | ||||||
|                 } catch { |                 } catch { | ||||||
|                     // User cancelled.
 |                     // User cancelled.
 | ||||||
|                 }; |                 }; | ||||||
|  | |||||||
| @ -28,7 +28,7 @@ | |||||||
|                     {{ 'core.login.signuprequiredfieldnotsupported' | translate }} |                     {{ 'core.login.signuprequiredfieldnotsupported' | translate }} | ||||||
|                 </ion-label> |                 </ion-label> | ||||||
|             </ion-item> |             </ion-item> | ||||||
|             <ion-button expand="block" class="ion-margin" [href]="signupUrl" core-link autoLogin="no"> |             <ion-button expand="block" class="ion-margin" [href]="signupUrl" core-link autoLogin="no" [showBrowserWarning]="false"> | ||||||
|                 {{ 'core.openinbrowser' | translate }} |                 {{ 'core.openinbrowser' | translate }} | ||||||
|             </ion-button> |             </ion-button> | ||||||
|         </ion-list> |         </ion-list> | ||||||
|  | |||||||
| @ -384,7 +384,10 @@ export class CoreLoginEmailSignupPage implements OnInit { | |||||||
|      * Show contact information on site (we have to display again the age verification form). |      * Show contact information on site (we have to display again the age verification form). | ||||||
|      */ |      */ | ||||||
|     showContactOnSite(): void { |     showContactOnSite(): void { | ||||||
|         CoreUtils.openInBrowser(CoreTextUtils.concatenatePaths(this.siteUrl, '/login/verify_age_location.php')); |         CoreUtils.openInBrowser( | ||||||
|  |             CoreTextUtils.concatenatePaths(this.siteUrl, '/login/verify_age_location.php'), | ||||||
|  |             { showBrowserWarning: false }, | ||||||
|  |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -660,7 +660,7 @@ export class CoreLoginHelperProvider { | |||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         // Always open it in browser because the user might have the session stored in there.
 |         // Always open it in browser because the user might have the session stored in there.
 | ||||||
|         CoreUtils.openInBrowser(loginUrl); |         CoreUtils.openInBrowser(loginUrl, { showBrowserWarning: false }); | ||||||
|         CoreApp.closeApp(); |         CoreApp.closeApp(); | ||||||
| 
 | 
 | ||||||
|         return true; |         return true; | ||||||
| @ -692,7 +692,7 @@ export class CoreLoginHelperProvider { | |||||||
|                 closebuttoncaption: Translate.instant('core.login.cancel'), |                 closebuttoncaption: Translate.instant('core.login.cancel'), | ||||||
|             }); |             }); | ||||||
|         } else { |         } else { | ||||||
|             CoreUtils.openInBrowser(loginUrl); |             CoreUtils.openInBrowser(loginUrl, { showBrowserWarning: false }); | ||||||
|             CoreApp.closeApp(); |             CoreApp.closeApp(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -30,8 +30,8 @@ | |||||||
|                         </p> |                         </p> | ||||||
|                         <p>{{ 'core.settings.license' | translate }}{{ 'core.labelsep' | translate }} {{ license.licenses }}</p> |                         <p>{{ 'core.settings.license' | translate }}{{ 'core.labelsep' | translate }} {{ license.licenses }}</p> | ||||||
|                         <p><a *ngIf="license.url" [href]="license.url" core-link auto-login="no">{{ license.url }}</a></p> |                         <p><a *ngIf="license.url" [href]="license.url" core-link auto-login="no">{{ license.url }}</a></p> | ||||||
|                         <p><a *ngIf="license.email" [href]="'mailto:' + license.email" core-link |                         <p><a *ngIf="license.email" [href]="'mailto:' + license.email" core-link auto-login="no" | ||||||
|                                 auto-login="no">{{ license.email }}</a></p> |                             [showBrowserWarning]="false">{{ license.email }}</a></p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|                     <ion-button *ngIf="license.licenseUrl" [href]="license.licenseUrl" target="_blank" |                     <ion-button *ngIf="license.licenseUrl" [href]="license.licenseUrl" target="_blank" | ||||||
|                         fill="clear" slot="end" core-link auto-login="no">{{ 'core.view' | translate }}</ion-button> |                         fill="clear" slot="end" core-link auto-login="no">{{ 'core.view' | translate }}</ion-button> | ||||||
|  | |||||||
| @ -17,7 +17,8 @@ | |||||||
|                 <ion-item class="ion-text-wrap" *ngIf="user.email"> |                 <ion-item class="ion-text-wrap" *ngIf="user.email"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <h2>{{ 'core.user.email' | translate }}</h2> |                         <h2>{{ 'core.user.email' | translate }}</h2> | ||||||
|                         <p><a class="core-anchor" href="mailto:{{user.email}}" core-link auto-login="no"> |                         <p><a class="core-anchor" href="mailto:{{user.email}}" core-link auto-login="no" | ||||||
|  |                                 [showBrowserWarning]="false"> | ||||||
|                             {{ user.email }} |                             {{ user.email }} | ||||||
|                         </a></p> |                         </a></p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
| @ -25,7 +26,7 @@ | |||||||
|                 <ion-item class="ion-text-wrap" *ngIf="user.phone1"> |                 <ion-item class="ion-text-wrap" *ngIf="user.phone1"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <h2>{{ 'core.user.phone1' | translate}}</h2> |                         <h2>{{ 'core.user.phone1' | translate}}</h2> | ||||||
|                         <p><a class="core-anchor" href="tel:{{user.phone1}}" core-link auto-login="no"> |                         <p><a class="core-anchor" href="tel:{{user.phone1}}" core-link auto-login="no" [showBrowserWarning]="false"> | ||||||
|                             {{ user.phone1 }} |                             {{ user.phone1 }} | ||||||
|                         </a></p> |                         </a></p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
| @ -33,7 +34,7 @@ | |||||||
|                 <ion-item class="ion-text-wrap" *ngIf="user.phone2"> |                 <ion-item class="ion-text-wrap" *ngIf="user.phone2"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <h2>{{ 'core.user.phone2' | translate}}</h2> |                         <h2>{{ 'core.user.phone2' | translate}}</h2> | ||||||
|                         <p><a class="core-anchor" href="tel:{{user.phone2}}" core-link auto-login="no"> |                         <p><a class="core-anchor" href="tel:{{user.phone2}}" core-link auto-login="no" [showBrowserWarning]="false"> | ||||||
|                             {{ user.phone2 }} |                             {{ user.phone2 }} | ||||||
|                         </a></p> |                         </a></p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
| @ -41,7 +42,7 @@ | |||||||
|                 <ion-item class="ion-text-wrap" *ngIf="formattedAddress"> |                 <ion-item class="ion-text-wrap" *ngIf="formattedAddress"> | ||||||
|                     <ion-label> |                     <ion-label> | ||||||
|                         <h2>{{ 'core.user.address' | translate}}</h2> |                         <h2>{{ 'core.user.address' | translate}}</h2> | ||||||
|                         <p><a class="core-anchor" [href]="encodedAddress" core-link auto-login="no"> |                         <p><a class="core-anchor" [href]="encodedAddress" core-link auto-login="no" [showBrowserWarning]="false"> | ||||||
|                             {{ formattedAddress }} |                             {{ formattedAddress }} | ||||||
|                         </a></p> |                         </a></p> | ||||||
|                     </ion-label> |                     </ion-label> | ||||||
|  | |||||||
| @ -56,7 +56,7 @@ export class CoreUserProfileMailHandlerService implements CoreUserProfileHandler | |||||||
|                 event.preventDefault(); |                 event.preventDefault(); | ||||||
|                 event.stopPropagation(); |                 event.stopPropagation(); | ||||||
| 
 | 
 | ||||||
|                 CoreUtils.openInBrowser('mailto:' + user.email); |                 CoreUtils.openInBrowser('mailto:' + user.email, { showBrowserWarning: false }); | ||||||
|             }, |             }, | ||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -86,6 +86,7 @@ | |||||||
|     "dismiss": "Dismiss", |     "dismiss": "Dismiss", | ||||||
|     "displayoptions": "Display options", |     "displayoptions": "Display options", | ||||||
|     "done": "Done", |     "done": "Done", | ||||||
|  |     "dontshowagain": "Don't show again.", | ||||||
|     "download": "Download", |     "download": "Download", | ||||||
|     "downloaded": "Downloaded", |     "downloaded": "Downloaded", | ||||||
|     "downloadfile": "Download file", |     "downloadfile": "Download file", | ||||||
| @ -327,6 +328,7 @@ | |||||||
|     "viewembeddedcontent": "View embedded content", |     "viewembeddedcontent": "View embedded content", | ||||||
|     "viewprofile": "View profile", |     "viewprofile": "View profile", | ||||||
|     "warningofflinedatadeleted": "Offline data from {{component}} '{{name}}' has been deleted. {{error}}", |     "warningofflinedatadeleted": "Offline data from {{component}} '{{name}}' has been deleted. {{error}}", | ||||||
|  |     "warnopeninbrowser": "<p>You are about to leave the app to open the following URL in your device's browser. Do you want to continue?</p>\n<p><b>{{url}}</b></p>", | ||||||
|     "whatisyourage": "What is your age?", |     "whatisyourage": "What is your age?", | ||||||
|     "wheredoyoulive": "In which country do you live?", |     "wheredoyoulive": "In which country do you live?", | ||||||
|     "whoissiteadmin": "\"Site Administrators\" are the people who manage the Moodle at your school/university/company or learning organisation. If you don't know how to contact them, please contact your teachers/trainers.", |     "whoissiteadmin": "\"Site Administrators\" are the people who manage the Moodle at your school/university/company or learning organisation. If you don't know how to contact them, please contact your teachers/trainers.", | ||||||
|  | |||||||
| @ -731,7 +731,7 @@ export class CoreSitesProvider { | |||||||
|                     Translate.instant('core.updaterequired'), |                     Translate.instant('core.updaterequired'), | ||||||
|                     Translate.instant('core.download'), |                     Translate.instant('core.download'), | ||||||
|                     Translate.instant(siteId ? 'core.mainmenu.logout' : 'core.cancel'), |                     Translate.instant(siteId ? 'core.mainmenu.logout' : 'core.cancel'), | ||||||
|                 ).then(() => CoreUtils.openInBrowser(downloadUrl)).catch(() => { |                 ).then(() => CoreUtils.openInBrowser(downloadUrl, { showBrowserWarning: false })).catch(() => { | ||||||
|                     // Do nothing.
 |                     // Do nothing.
 | ||||||
|                 }); |                 }); | ||||||
|             } else { |             } else { | ||||||
|  | |||||||
| @ -1440,7 +1440,7 @@ export class CoreDomUtilsProvider { | |||||||
|             buttons.push({ |             buttons.push({ | ||||||
|                 text: Translate.instant('core.download'), |                 text: Translate.instant('core.download'), | ||||||
|                 handler: (): void => { |                 handler: (): void => { | ||||||
|                     CoreUtils.openInBrowser(link); |                     CoreUtils.openInBrowser(link, { showBrowserWarning: false }); | ||||||
|                 }, |                 }, | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
| @ -1465,28 +1465,32 @@ export class CoreDomUtilsProvider { | |||||||
|      * |      * | ||||||
|      * @param message Modal message. |      * @param message Modal message. | ||||||
|      * @param header Modal header. |      * @param header Modal header. | ||||||
|      * @param placeholder Placeholder of the input element. By default, "Password". |      * @param placeholderOrLabel Placeholder (for textual/numeric inputs) or label (for radio/checkbox). By default, "Password". | ||||||
|      * @param type Type of the input element. By default, password. |      * @param type Type of the input element. By default, password. | ||||||
|      * @param options More options to pass to the alert. |      * @param options More options to pass to the alert. | ||||||
|      * @return Promise resolved with the input data if the user clicks OK, rejected if cancels. |      * @return Promise resolved with the input data (true for checkbox/radio) if the user clicks OK, rejected if cancels. | ||||||
|      */ |      */ | ||||||
|     showPrompt( |     showPrompt( | ||||||
|         message: string, |         message: string, | ||||||
|         header?: string, |         header?: string, | ||||||
|         placeholder?: string, |         placeholderOrLabel?: string, | ||||||
|         type: TextFieldTypes | 'checkbox' | 'radio' | 'textarea' = 'password', |         type: TextFieldTypes | 'checkbox' | 'radio' | 'textarea' = 'password', | ||||||
|     ): Promise<any> { // eslint-disable-line @typescript-eslint/no-explicit-any
 |     ): Promise<any> { // eslint-disable-line @typescript-eslint/no-explicit-any
 | ||||||
|         return new Promise((resolve, reject) => { |         return new Promise((resolve, reject) => { | ||||||
|             placeholder = placeholder ?? Translate.instant('core.login.password'); |             placeholderOrLabel = placeholderOrLabel ?? Translate.instant('core.login.password'); | ||||||
| 
 | 
 | ||||||
|  |             const isCheckbox = type === 'checkbox'; | ||||||
|  |             const isRadio = type === 'radio'; | ||||||
|             const options: AlertOptions = { |             const options: AlertOptions = { | ||||||
|                 header, |                 header, | ||||||
|                 message, |                 message, | ||||||
|                 inputs: [ |                 inputs: [ | ||||||
|                     { |                     { | ||||||
|                         name: 'promptinput', |                         name: 'promptinput', | ||||||
|                         placeholder: placeholder, |                         placeholder: placeholderOrLabel, | ||||||
|  |                         label: placeholderOrLabel, | ||||||
|                         type, |                         type, | ||||||
|  |                         value: (isCheckbox || isRadio) ? true : undefined, | ||||||
|                     }, |                     }, | ||||||
|                 ], |                 ], | ||||||
|                 buttons: [ |                 buttons: [ | ||||||
| @ -1500,7 +1504,13 @@ export class CoreDomUtilsProvider { | |||||||
|                     { |                     { | ||||||
|                         text: Translate.instant('core.ok'), |                         text: Translate.instant('core.ok'), | ||||||
|                         handler: (data) => { |                         handler: (data) => { | ||||||
|                             resolve(data.promptinput); |                             if (isCheckbox) { | ||||||
|  |                                 resolve(data[0]); | ||||||
|  |                             } else if (isRadio) { | ||||||
|  |                                 resolve(data); | ||||||
|  |                             } else { | ||||||
|  |                                 resolve(data.promptinput); | ||||||
|  |                             } | ||||||
|                         }, |                         }, | ||||||
|                     }, |                     }, | ||||||
|                 ], |                 ], | ||||||
|  | |||||||
| @ -32,6 +32,7 @@ import { CoreViewerQRScannerComponent } from '@features/viewer/components/qr-sca | |||||||
| import { CoreCanceledError } from '@classes/errors/cancelederror'; | import { CoreCanceledError } from '@classes/errors/cancelederror'; | ||||||
| import { CoreFileEntry } from '@services/file-helper'; | import { CoreFileEntry } from '@services/file-helper'; | ||||||
| import { CoreConstants } from '@/core/constants'; | import { CoreConstants } from '@/core/constants'; | ||||||
|  | import { CoreWindow } from '@singletons/window'; | ||||||
| 
 | 
 | ||||||
| type TreeNode<T> = T & { children: TreeNode<T>[] }; | type TreeNode<T> = T & { children: TreeNode<T>[] }; | ||||||
| 
 | 
 | ||||||
| @ -1047,8 +1048,17 @@ export class CoreUtilsProvider { | |||||||
|      * Do not use for files, refer to {@link openFile}. |      * Do not use for files, refer to {@link openFile}. | ||||||
|      * |      * | ||||||
|      * @param url The URL to open. |      * @param url The URL to open. | ||||||
|  |      * @param options Options. | ||||||
|      */ |      */ | ||||||
|     openInBrowser(url: string): void { |     async openInBrowser(url: string, options: CoreUtilsOpenInBrowserOptions = {}): Promise<void> { | ||||||
|  |         if (options.showBrowserWarning || options.showBrowserWarning === undefined) { | ||||||
|  |             try { | ||||||
|  |                 await CoreWindow.confirmOpenBrowserIfNeeded(url); | ||||||
|  |             } catch (error) { | ||||||
|  |                 return; // Cancelled, stop.
 | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         window.open(url, '_system'); |         window.open(url, '_system'); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -1727,6 +1737,13 @@ export type CoreUtilsOpenFileOptions = { | |||||||
|     iOSOpenFileAction?: OpenFileAction; // Action to do when opening a file.
 |     iOSOpenFileAction?: OpenFileAction; // Action to do when opening a file.
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /** | ||||||
|  |  * Options for opening in browser. | ||||||
|  |  */ | ||||||
|  | export type CoreUtilsOpenInBrowserOptions = { | ||||||
|  |     showBrowserWarning?: boolean; // Whether to display a warning before opening in browser. Defaults to true.
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * Possible default picker actions. |  * Possible default picker actions. | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -14,11 +14,15 @@ | |||||||
| 
 | 
 | ||||||
| import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper'; | import { CoreContentLinksHelper } from '@features/contentlinks/services/contentlinks-helper'; | ||||||
| import { NavController } from '@ionic/angular'; | import { NavController } from '@ionic/angular'; | ||||||
|  | import { CoreConfig } from '@services/config'; | ||||||
| 
 | 
 | ||||||
| import { CoreFileHelper } from '@services/file-helper'; | import { CoreFileHelper } from '@services/file-helper'; | ||||||
| import { CoreSites } from '@services/sites'; | import { CoreSites } from '@services/sites'; | ||||||
|  | import { CoreDomUtils } from '@services/utils/dom'; | ||||||
| import { CoreUrlUtils } from '@services/utils/url'; | import { CoreUrlUtils } from '@services/utils/url'; | ||||||
| import { CoreUtils } from '@services/utils/utils'; | import { CoreUtils } from '@services/utils/utils'; | ||||||
|  | import { Translate } from '@singletons'; | ||||||
|  | import { CoreConstants } from '../constants'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Options for the open function. |  * Options for the open function. | ||||||
| @ -44,6 +48,31 @@ export class CoreWindow { | |||||||
|         // Nothing to do.
 |         // Nothing to do.
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Show a confirm before opening a link in browser, unless the user previously marked to not show again. | ||||||
|  |      * | ||||||
|  |      * @param url URL to open. | ||||||
|  |      * @return Promise resolved if confirmed, rejected if rejected. | ||||||
|  |      */ | ||||||
|  |     static async confirmOpenBrowserIfNeeded(url: string): Promise<void> { | ||||||
|  |         // Check if the user decided not to see the warning.
 | ||||||
|  |         const dontShowWarning = await CoreConfig.get(CoreConstants.SETTINGS_DONT_SHOW_EXTERNAL_LINK_WARN, 0); | ||||||
|  |         if (dontShowWarning) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const dontShowAgain = await CoreDomUtils.showPrompt( | ||||||
|  |             Translate.instant('core.warnopeninbrowser', { url }), | ||||||
|  |             undefined, | ||||||
|  |             Translate.instant('core.dontshowagain'), | ||||||
|  |             'checkbox', | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |         if (dontShowAgain) { | ||||||
|  |             CoreConfig.set(CoreConstants.SETTINGS_DONT_SHOW_EXTERNAL_LINK_WARN, 1); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * "Safe" implementation of window.open. It will open the URL without overriding the app. |      * "Safe" implementation of window.open. It will open the URL without overriding the app. | ||||||
|      * |      * | ||||||
| @ -73,12 +102,12 @@ export class CoreWindow { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (!treated) { |             if (!treated) { | ||||||
|                 // Not opened in the app, open with browser. Check if we need to auto-login
 |                 // Not opened in the app, open with browser. Check if we need to auto-login.
 | ||||||
|                 if (!CoreSites.isLoggedIn()) { |                 if (!CoreSites.isLoggedIn()) { | ||||||
|                     // Not logged in, cannot auto-login.
 |                     // Not logged in, cannot auto-login.
 | ||||||
|                     CoreUtils.openInBrowser(url); |                     CoreUtils.openInBrowser(url); | ||||||
|                 } else { |                 } else { | ||||||
|                     await CoreSites.getCurrentSite()!.openInBrowserWithAutoLoginIfSameSite(url); |                     await CoreSites.getRequiredCurrentSite().openInBrowserWithAutoLoginIfSameSite(url); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user