mirror of https://github.com/Squidex/squidex.git
committed by
GitHub
32 changed files with 517 additions and 333 deletions
@ -1,6 +1,66 @@ |
|||
@import 'mixins'; |
|||
@import 'vars'; |
|||
|
|||
:host ::ng-deep { |
|||
.modal-body { |
|||
background-color: $color-background; |
|||
} |
|||
} |
|||
|
|||
form { |
|||
width: 100%; |
|||
} |
|||
|
|||
textarea { |
|||
height: 300px; |
|||
} |
|||
|
|||
.flex-reverse { |
|||
flex-direction: row-reverse; |
|||
} |
|||
|
|||
.bubble { |
|||
background-color: $color-white; |
|||
border: 0; |
|||
border-radius: $border-radius; |
|||
padding: 1rem; |
|||
position: relative; |
|||
|
|||
&-right { |
|||
&::before { |
|||
@include caret-left($color-white, 10px); |
|||
@include absolute(.5rem, null, null, -18px); |
|||
} |
|||
} |
|||
|
|||
&-left { |
|||
&::before { |
|||
@include caret-right($color-white, 10px); |
|||
@include absolute(.5rem, -18px); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@keyframes blink { |
|||
50% { |
|||
fill: transparent |
|||
} |
|||
} |
|||
|
|||
.dot { |
|||
animation: 1s blink infinite; |
|||
} |
|||
|
|||
svg { |
|||
.dot { |
|||
fill: $color-border; |
|||
} |
|||
} |
|||
|
|||
.dot:nth-child(2) { |
|||
animation-delay: 250ms; |
|||
} |
|||
|
|||
.dot:nth-child(3) { |
|||
animation-delay: 500ms; |
|||
} |
|||
@ -1,7 +1,7 @@ |
|||
<div class="copy-container"> |
|||
<button type="button" class="code-copy" [sqxCopy]="codeBlock"> |
|||
<div class="code-container"> |
|||
<button type="button" class="code-copy" [attr.copy]="id"> |
|||
<i class="icon-copy"></i> |
|||
</button> |
|||
|
|||
<pre class="code" #codeBlock><ng-content></ng-content></pre> |
|||
<pre class="code" [attr.id]="id"><ng-content></ng-content></pre> |
|||
</div> |
|||
@ -1,34 +1,2 @@ |
|||
@import 'mixins'; |
|||
@import 'vars'; |
|||
|
|||
.code { |
|||
background: $color-code-background; |
|||
margin: .25rem 0; |
|||
padding-left: .5rem; |
|||
padding-right: 3rem; |
|||
} |
|||
|
|||
.code, |
|||
.code-copy { |
|||
@include text-code; |
|||
min-height: 27px; |
|||
padding-bottom: .25rem; |
|||
padding-top: .25rem; |
|||
} |
|||
|
|||
.copy-container { |
|||
position: relative; |
|||
} |
|||
|
|||
.code-copy { |
|||
@include absolute(0, 0, auto, auto); |
|||
background: darken($color-border-dark, 30%); |
|||
border: 0; |
|||
color: $color-white; |
|||
padding-left: .375rem; |
|||
padding-right: .375rem; |
|||
|
|||
&:focus { |
|||
background: darken($color-border-dark, 40%); |
|||
} |
|||
} |
|||
@import 'vars'; |
|||
@ -0,0 +1,91 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
|||
*/ |
|||
|
|||
import { Directive, HostListener, Renderer2 } from '@angular/core'; |
|||
import { DialogService, Types } from '@app/framework/internal'; |
|||
|
|||
@Directive({ |
|||
selector: '[sqxCopyGlobal]', |
|||
}) |
|||
export class CopyGlobalDirective { |
|||
constructor( |
|||
private readonly dialogs: DialogService, |
|||
private readonly renderer: Renderer2, |
|||
) { |
|||
} |
|||
|
|||
@HostListener('document:click', ['$event']) |
|||
public onClick(event: MouseEvent) { |
|||
function findElement(target: HTMLElement | null): string | null { |
|||
if (!target) { |
|||
return null; |
|||
} |
|||
|
|||
const id = target.getAttribute('copy')!; |
|||
|
|||
if (id) { |
|||
return id; |
|||
} |
|||
|
|||
return findElement(target.parentElement); |
|||
} |
|||
|
|||
const toCopy = document.getElementById(findElement(event.target as any)!); |
|||
|
|||
if (!toCopy) { |
|||
return; |
|||
} |
|||
|
|||
this.copyToClipbord(toCopy); |
|||
} |
|||
|
|||
private copyToClipbord(element: HTMLElement) { |
|||
if (Types.is(element, HTMLInputElement) || Types.is(element, HTMLTextAreaElement)) { |
|||
const currentFocus: any = document.activeElement; |
|||
|
|||
const prevSelectionStart = element.selectionStart; |
|||
const prevSelectionEnd = element.selectionEnd; |
|||
|
|||
element.focus(); |
|||
element.setSelectionRange(0, element.value.length); |
|||
|
|||
this.copy(); |
|||
|
|||
element.setSelectionRange(prevSelectionStart!, prevSelectionEnd!); |
|||
|
|||
if (currentFocus && Types.isFunction(currentFocus.focus)) { |
|||
currentFocus.focus(); |
|||
} |
|||
} else { |
|||
const input = this.renderer.createElement('textarea'); |
|||
|
|||
this.renderer.setStyle(input, 'position', 'absolute'); |
|||
this.renderer.setStyle(input, 'right', '-1000px'); |
|||
this.renderer.appendChild(document.body, input); |
|||
|
|||
input.value = element.innerText; |
|||
input.select(); |
|||
|
|||
this.copy(); |
|||
|
|||
this.renderer.removeChild(document.body, input); |
|||
} |
|||
} |
|||
|
|||
private copy() { |
|||
try { |
|||
// eslint-disable-next-line deprecation/deprecation
|
|||
document.execCommand('copy'); |
|||
|
|||
this.dialogs.notifyInfo('i18n:common.clipboardAdded'); |
|||
|
|||
return true; |
|||
} catch (e) { |
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue