Now based on mailtoui
This commit is contained in:
parent
4266ba931a
commit
f35b067076
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"box-model": false,
|
||||
"box-sizing": false,
|
||||
"outline-none": false
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
/dist
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 8,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": ["prettier"],
|
||||
"extends": ["plugin:prettier/recommended"],
|
||||
"rules": {
|
||||
"prettier/prettier": [
|
||||
"error",
|
||||
{
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"printWidth": 125,
|
||||
"tabWidth": 4,
|
||||
"useTabs": false,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": true,
|
||||
"parser": "flow"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2020": true
|
||||
},
|
||||
"extends": [
|
||||
"airbnb-base"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
}
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
node_modules
|
||||
/node_modules
|
||||
.DS_Store
|
||||
.cache
|
||||
yarn.lock
|
||||
.eslintrc.json
|
||||
.vscode
|
||||
serve
|
||||
compile
|
||||
publish
|
||||
|
|
71
README.md
71
README.md
|
@ -1,22 +1,59 @@
|
|||
# 📧 mailymaily
|
||||
<p align="center">
|
||||
<a href="https://mailtoui.com">
|
||||
<img src="https://mailtoui.com/assets/img/heading.jpg" alt="MailtoUI">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## Usage
|
||||
### CC
|
||||
`data-cc-address` and `data-cc-domain` to recreate cc: `data-cc-address@data-cc-domain`
|
||||
### BCC
|
||||
`data-bcc-address` and `data-bcc-domain` to recreate bcc: `data-bcc-address@data-bcc-domain`
|
||||
### Subject
|
||||
`data-subject` for the subject of the email
|
||||
### Body
|
||||
`data-body` for the body of the email
|
||||
<p align="center">A simple way to enhance your mailto links with a convenient user interface.</p>
|
||||
|
||||
## Dev
|
||||
### Dependencies
|
||||
```
|
||||
yarn
|
||||
<p align="center">
|
||||
<a href="https://github.com/mariordev/mailtoui/releases"><img src="https://img.shields.io/npm/v/mailtoui.svg" alt="Latest release"></a>
|
||||
<a href="https://www.npmjs.com/package/mailtoui"><img src="https://img.shields.io/npm/dt/mailtoui.svg" alt="Total downloads"></a>
|
||||
<a href="https://github.com/mariordev/mailtoui/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mariordev/mailtoui.svg" alt="License"></a>
|
||||
<a href="https://twitter.com/intent/tweet?text=Check%20this%20out!%20&url=https%3A%2F%2Fmailtoui.com"><img src="https://img.shields.io/twitter/url/https/mailtoui.com.svg?style=social" alt="Share on Twitter"></a>
|
||||
</p>
|
||||
|
||||
## Introduction
|
||||
|
||||
MailtoUI is a JavaScript library that enhances your mailto links with a convenient user interface. It gives your users the flexibility to compose a new message using a browser-based email client <strong><i>or</i></strong> their default local email app.
|
||||
|
||||
MailtoUI is ideal for static sites or any other site where you don't want to spend time setting up a "Contact Us" form solution.
|
||||
|
||||
## Quick Setup
|
||||
|
||||
### STEP 1
|
||||
|
||||
Add MailtoUI via CDN to the bottom of your page, just before the closing `</body>` tag.
|
||||
|
||||
IMPORTANT: Be sure to replace `[version]` with the latest version number.
|
||||
|
||||
```html
|
||||
<body>
|
||||
...
|
||||
...
|
||||
<script src="https://cdn.jsdelivr.net/npm/mailtoui@[version]/dist/mailtoui-min.js"></script>
|
||||
</body>
|
||||
```
|
||||
|
||||
### Building
|
||||
### STEP 2
|
||||
|
||||
Attach your mailto link to MailtoUI by adding the class `mailtoui` to the `<a>` tag.
|
||||
|
||||
```html
|
||||
<a class="mailtoui" href="mailto:tony.stark@example.com">Contact Tony</a>
|
||||
```
|
||||
yarn build
|
||||
```
|
||||
|
||||
That's it! Your mailto link is now using MailtoUI. Refresh your page and try it out.
|
||||
|
||||
|
||||
## Documentation
|
||||
|
||||
For full documentation, visit [mailtoui.com](https://mailtoui.com).
|
||||
|
||||
## Contributing
|
||||
|
||||
If you're interested in contributing to MailtoUI, please follow the directions in the [contributing docs](https://github.com/mariordev/mailtoui/blob/master/.github/CONTRIBUTING.md) **before working on a pull request**.
|
||||
|
||||
## License
|
||||
|
||||
[MIT](https://github.com/mariordev/mailtoui/blob/master/LICENSE)
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
const presets = [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
browsers: [ 'defaults' ]
|
||||
}
|
||||
}
|
||||
],
|
||||
'@babel/preset-typescript'
|
||||
];
|
||||
|
||||
module.exports = { presets };
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,138 @@
|
|||
const { src, dest, parallel, series, watch } = require('gulp');
|
||||
const csslint = require('gulp-csslint');
|
||||
const autoprefixer = require('gulp-autoprefixer');
|
||||
const minify = require('gulp-minify');
|
||||
const cleanCss = require('gulp-clean-css');
|
||||
const rename = require('gulp-rename');
|
||||
const header = require('gulp-header');
|
||||
const eslint = require('gulp-eslint');
|
||||
const fs = require('fs-extra');
|
||||
const htmlMin = require('gulp-htmlmin');
|
||||
const browserify = require('browserify');
|
||||
const source = require('vinyl-source-stream');
|
||||
const buffer = require('vinyl-buffer');
|
||||
const sass = require('gulp-sass');
|
||||
|
||||
var packageJson = null;
|
||||
var banner = [
|
||||
'/**',
|
||||
' * <%= pkg.name %> - <%= pkg.description %>',
|
||||
' * @version v<%= pkg.version %>',
|
||||
' * @link <%= pkg.homepage %>',
|
||||
' * @author <%= pkg.author.name %> - <%= pkg.author.url %>',
|
||||
' * @license <%= pkg.license %>',
|
||||
' */',
|
||||
''
|
||||
].join('\n');
|
||||
|
||||
/**
|
||||
* Process HTML files.
|
||||
*/
|
||||
function html() {
|
||||
return src('./src/html/component.html')
|
||||
.pipe(htmlMin({ collapseWhitespace: true }))
|
||||
.pipe(rename('./src/html/component-min.html'))
|
||||
.pipe(dest('./'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Process CSS file.
|
||||
*/
|
||||
function css() {
|
||||
return src('./src/scss/component.scss')
|
||||
.pipe(sass())
|
||||
.pipe(csslint())
|
||||
.pipe(csslint.formatter())
|
||||
.pipe(
|
||||
autoprefixer({
|
||||
browsers: ['last 2 versions'],
|
||||
cascade: false
|
||||
})
|
||||
)
|
||||
.pipe(cleanCss())
|
||||
.pipe(rename('./src/css/component-min.css'))
|
||||
.pipe(dest('./'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the JavaScript library file.
|
||||
*/
|
||||
function js() {
|
||||
packageJson = fs.readJsonSync('./package.json');
|
||||
|
||||
return src('./src/js/mailtoui.js')
|
||||
.pipe(eslint())
|
||||
.pipe(eslint.format())
|
||||
.pipe(minify({ noSource: true }))
|
||||
.pipe(header(banner, { pkg: packageJson }))
|
||||
.pipe(dest('dist'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Lint JavaScript file used on demo page.
|
||||
*/
|
||||
function lintDemoJs() {
|
||||
return src('./demo/demo.js')
|
||||
.pipe(eslint())
|
||||
.pipe(eslint.format());
|
||||
}
|
||||
|
||||
/**
|
||||
* Process JavaScript file used on demo page.
|
||||
*/
|
||||
function processDemoJs() {
|
||||
return browserify('./demo/demo.js')
|
||||
.bundle()
|
||||
.pipe(source('./demo/demo.js'))
|
||||
.pipe(buffer())
|
||||
.pipe(minify({ noSource: true }))
|
||||
.pipe(dest('./'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Process CSS file used on demo page.
|
||||
*/
|
||||
function demoCss() {
|
||||
return src('./demo/demo.scss')
|
||||
.pipe(sass())
|
||||
.pipe(csslint())
|
||||
.pipe(csslint.formatter())
|
||||
.pipe(
|
||||
autoprefixer({
|
||||
browsers: ['last 2 versions'],
|
||||
cascade: false
|
||||
})
|
||||
)
|
||||
.pipe(cleanCss())
|
||||
.pipe(rename('./demo/demo-min.css'))
|
||||
.pipe(dest('./'));
|
||||
}
|
||||
|
||||
/**
|
||||
* The all seeing eye...
|
||||
*/
|
||||
function watchFiles() {
|
||||
watch('./src/html/component.html', html);
|
||||
watch('./src/scss/component.scss', css);
|
||||
watch(['./src/js/mailtoui.js', './package.json'], series(js, lintDemoJs, processDemoJs));
|
||||
watch('./demo/demo.scss', demoCss);
|
||||
watch('./demo/demo.js', demoJs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define complex tasks.
|
||||
*/
|
||||
const demoJs = series(lintDemoJs, processDemoJs);
|
||||
const build = series(parallel(html, css), js, demoJs, demoCss);
|
||||
const watching = series(build, watchFiles);
|
||||
|
||||
/**
|
||||
* Make tasks available to the outside world.
|
||||
*/
|
||||
exports.html = html;
|
||||
exports.css = css;
|
||||
exports.js = js;
|
||||
exports.demoJs = demoJs;
|
||||
exports.demoCss = demoCss;
|
||||
exports.watch = watching;
|
||||
exports.default = build;
|
|
@ -1,32 +0,0 @@
|
|||
{
|
||||
"languages": [ "en", "de" ],
|
||||
"translations": {
|
||||
"en": {
|
||||
"open_in_": "open in ",
|
||||
"cc_": "cc ",
|
||||
"bcc_": "bcc ",
|
||||
"subject_": "subject ",
|
||||
"body_": "body ",
|
||||
"gmail": "Gmail",
|
||||
"outlook": "Outlook",
|
||||
"telegram": "Telegram",
|
||||
"whatsapp": "WhatsApp",
|
||||
"skype": "Skype",
|
||||
"call": "call",
|
||||
"open": "open",
|
||||
"_default": " default",
|
||||
"_as_default": " as default",
|
||||
"copy": "copy"
|
||||
},
|
||||
"de": {
|
||||
"open_in_": "Öffnen in ",
|
||||
"subject_": "Betreff ",
|
||||
"body_": "Nachricht ",
|
||||
"call": "Anrufen",
|
||||
"open": "Öffnen",
|
||||
"_default": " mit Standard Programm",
|
||||
"_as_default": " mit Standard Programm",
|
||||
"copy": "In die Zwischenablage kopieren"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
declare module 'mailgo' {
|
||||
export type MailgoConfig = {
|
||||
initEvent?: string;
|
||||
listenerOptions?: ListenerOptions | boolean;
|
||||
dark?: boolean;
|
||||
lang?: string;
|
||||
forceLang?: boolean;
|
||||
validateEmail?: boolean;
|
||||
validateTel?: boolean;
|
||||
showFooter?: boolean;
|
||||
};
|
||||
|
||||
export type MailgoTranslation = {
|
||||
open_in_?: string;
|
||||
cc_?: string;
|
||||
bcc_?: string;
|
||||
subject_?: string;
|
||||
body_?: string;
|
||||
gmail?: string;
|
||||
outlook?: string;
|
||||
whatsapp?: string;
|
||||
skype?: string;
|
||||
call?: string;
|
||||
open?: string;
|
||||
_default?: string;
|
||||
_as_default?: string;
|
||||
copy?: string;
|
||||
};
|
||||
|
||||
export type MailgoTranslations = {
|
||||
[language: string]: MailgoTranslation;
|
||||
};
|
||||
|
||||
export type MailgoI18n = {
|
||||
languages: string[];
|
||||
translations: MailgoTranslations;
|
||||
};
|
||||
|
||||
export type ListenerOptions = {
|
||||
capture?: boolean;
|
||||
once?: boolean;
|
||||
passive?: boolean;
|
||||
};
|
||||
|
||||
export function mailgoRender(type: string, mailgoElement: HTMLLinkElement): void;
|
||||
|
||||
export function isMailgo(element: HTMLElement, type?: string): boolean;
|
||||
|
||||
export function mailgoCheckRender(event: Event): boolean;
|
||||
|
||||
export default function mailgo(mailgoConfig?: MailgoConfig): void;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
91
package.json
91
package.json
|
@ -1,32 +1,61 @@
|
|||
{
|
||||
"name": "mailgo",
|
||||
"version": "0.9.14",
|
||||
"description": "a new concept of mailto and tel links",
|
||||
"scripts": {
|
||||
"build": "webpack"
|
||||
},
|
||||
"main": "./lib/mailgo.js",
|
||||
"module": "./lib/mailgo.js",
|
||||
"types": "./mailgo.d.ts",
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.10.5",
|
||||
"@babel/core": "^7.11.1",
|
||||
"@babel/parser": "^7.11.3",
|
||||
"@babel/preset-env": "^7.11.0",
|
||||
"@babel/preset-typescript": "^7.10.4",
|
||||
"@babel/types": "^7.11.0",
|
||||
"@types/node": "^14.0.27",
|
||||
"babel-loader": "^8.1.0",
|
||||
"css-loader": "^4.2.1",
|
||||
"node-sass": "^4.14.1",
|
||||
"sass-loader": "^9.0.3",
|
||||
"style-loader": "^1.2.1",
|
||||
"to-string-loader": "^1.1.6",
|
||||
"ts-loader": "^8.0.2",
|
||||
"typescript": "^3.9.7",
|
||||
"webpack": "^4.44.1",
|
||||
"webpack-cli": "^3.3.12"
|
||||
},
|
||||
"dependencies": {},
|
||||
"sideEffects": false
|
||||
}
|
||||
"name": "mailtoui",
|
||||
"description": "A simple way to enhance your mailto links with a convenient user interface.",
|
||||
"version": "1.0.3",
|
||||
"homepage": "https://mailtoui.com",
|
||||
"author": {
|
||||
"name": "Mario Rodriguez",
|
||||
"url": "https://twitter.com/mariordev"
|
||||
},
|
||||
"keywords": [
|
||||
"mailtoui",
|
||||
"mailto",
|
||||
"ui",
|
||||
"mail",
|
||||
"email",
|
||||
"interface",
|
||||
"user interface"
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": "https://github.com/mariordev/mailtoui.git",
|
||||
"bugs": "https://github.com/mariordev/mailtoui/issues",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.5.5",
|
||||
"@babel/plugin-transform-regenerator": "^7.4.5",
|
||||
"@babel/preset-env": "^7.5.5",
|
||||
"acorn": "^6.3.0",
|
||||
"babelify": "^10.0.0",
|
||||
"browserify": "^16.5.0",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-config-prettier": "^3.6.0",
|
||||
"eslint-plugin-prettier": "^3.1.0",
|
||||
"fs-extra": "^7.0.1",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-autoprefixer": "^6.1.0",
|
||||
"gulp-clean-css": "^4.2.0",
|
||||
"gulp-csslint": "^1.0.1",
|
||||
"gulp-eslint": "^5.0.0",
|
||||
"gulp-header": "^2.0.9",
|
||||
"gulp-htmlmin": "^5.0.1",
|
||||
"gulp-minify": "^3.1.0",
|
||||
"gulp-rename": "^1.4.0",
|
||||
"gulp-sass": "^4.0.2",
|
||||
"gulp-util": "^3.0.8",
|
||||
"gulp-watch": "^5.0.1",
|
||||
"node-sass": "^4.12.0",
|
||||
"prettier": "1.15.3",
|
||||
"shell-quote": "^1.7.2",
|
||||
"tar": "^4.4.10",
|
||||
"vinyl-buffer": "^1.0.1",
|
||||
"vinyl-source-stream": "^2.0.0",
|
||||
"vue": "^2.6.10"
|
||||
},
|
||||
"dependencies": {},
|
||||
"files": [
|
||||
"dist/*"
|
||||
],
|
||||
"jsdelivr": "dist/mailtoui-min.js",
|
||||
"scripts": {
|
||||
"lint": "eslint ./src/js/mailtoui.js"
|
||||
}
|
||||
}
|
28
sample.html
28
sample.html
|
@ -1,28 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>mailymaily examples</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/open-fonts@1.1.1/fonts/inter.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@exampledev/new.css@1.1.2/new.min.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>📧 mailymaily</h1>
|
||||
<br>
|
||||
<h2>MailTo</h2>
|
||||
<h3>🌞 Light mode</h3>
|
||||
<a href="#mailgo" data-address="info" data-domain="odit.services">info@odit.services</a>
|
||||
<h3>🌑 Dark mode</h3>
|
||||
<a class="dark" href="#mailgo" data-address="info" data-domain="odit.services" data-cc="info@odit.services">info@odit.services</a><br>
|
||||
<br><br>
|
||||
<h2>CallTo</h2>
|
||||
<h3>🌞 Light mode</h3>
|
||||
<a href="callto:+493012345678">+493012345678</a>
|
||||
<h3>🌑 Dark mode</h3>
|
||||
<a class="dark" href="callto:+493012345678">+493012345678</a>
|
||||
<script src="./dist/mailgo.min.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
.mailtoui-modal{background-color:#000;background-color:rgba(0,0,0,.4);bottom:0;color:#303131;display:none;height:100%;left:0;margin:0;padding:0;position:fixed;right:0;top:0;width:100%;z-index:1000}.mailtoui-modal-content{-webkit-animation:mailtoui-appear .4s;animation:mailtoui-appear .4s;background-color:#f1f5f8;border-radius:8px;bottom:auto;-webkit-box-shadow:0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);box-shadow:0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19);left:50%;max-height:calc(100% - 100px);overflow:auto;padding:0;position:fixed;right:-45%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.mailtoui-modal-content:focus,.mailtoui-modal-content:hover{overflow-y:auto}@media only screen and (min-width:768px){.mailtoui-modal-content{right:auto}}.mailtoui-modal-head{-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:#fff;clear:both;display:-webkit-box;display:-ms-flexbox;display:flex;min-width:0;padding:10px 20px}.mailtoui-modal-title{color:#303131;-webkit-box-flex:1;-ms-flex:1;flex:1;font-family:sans-serif;font-size:120%;font-weight:700;margin:0;overflow:hidden;padding:0;text-overflow:ellipsis;white-space:nowrap}.mailtoui-modal-close{color:#aaa;-webkit-box-flex:initial;-ms-flex:initial;flex:initial;font-size:38px;margin-left:20px;position:relative;text-align:right;text-decoration:none;top:-4px}.mailtoui-modal-close:focus,.mailtoui-modal-close:hover{color:#000;cursor:pointer;font-weight:700;outline:0}.mailtoui-modal-body{height:100%;padding:20px}.mailtoui-button{color:#333;text-decoration:none}.mailtoui-button:focus{outline:0}.mailtoui-button:focus .mailtoui-button-content{background-color:#555;color:#fff}.mailtoui-button-content{background-color:#fff;border:none;border-radius:8px;-webkit-box-shadow:0 2px 4px rgba(0,0,0,.18);box-shadow:0 2px 4px rgba(0,0,0,.18);margin-bottom:20px;overflow:hidden;padding:15px 20px;text-overflow:ellipsis;white-space:nowrap}.mailtoui-button-content:hover{background-color:#555;color:#fff}.mailtoui-button:last-child .mailtoui-button-content{margin-bottom:0}.mailtoui-button-icon{display:inline-block;font-weight:700;position:relative;top:4px}.mailtoui-button-icon svg{height:24px;width:24px}.mailtoui-button-text{display:inline-block;margin-left:5px;position:relative;top:-2px}.mailtoui-copy{border-radius:8px;-webkit-box-shadow:0 2px 4px rgba(0,0,0,.18);box-shadow:0 2px 4px rgba(0,0,0,.18);height:59px;margin-top:20px;position:relative}.mailtoui-button-copy{background-color:#fff;border:none;border-bottom-left-radius:8px;border-top-left-radius:8px;bottom:21px;color:#333;font-size:100%;height:100%;left:0;overflow:hidden;padding:15px 20px;position:absolute;text-overflow:ellipsis;top:0;white-space:nowrap;width:120px}.mailtoui-button-copy:focus,.mailtoui-button-copy:hover{background-color:#555;color:#fff;cursor:pointer;outline:0}.mailtoui-button-copy-clicked,.mailtoui-button-copy-clicked:focus,.mailtoui-button-copy-clicked:hover{background-color:#1f9d55;color:#fff}.mailtoui-button-copy-clicked .mailtoui-button-icon,.mailtoui-button-copy-clicked:focus .mailtoui-button-icon,.mailtoui-button-copy-clicked:hover .mailtoui-button-icon{display:none;visibility:hidden}.mailtoui-button-copy-clicked .mailtoui-button-text,.mailtoui-button-copy-clicked:focus .mailtoui-button-text,.mailtoui-button-copy-clicked:hover .mailtoui-button-text{color:#fff;top:2px}.mailtoui-email-address{background-color:#d8dcdf;border:none;border-radius:8px;-webkit-box-shadow:unset;box-shadow:unset;-webkit-box-sizing:border-box;box-sizing:border-box;color:#48494a;font-size:100%;height:100%;overflow:hidden;padding:20px 20px 20px 140px;text-overflow:ellipsis;white-space:nowrap;width:100%}.mailtoui-brand{color:#888;font-size:80%;margin-top:20px;text-align:center}.mailtoui-brand a{color:#888}.mailtoui-brand a:focus,.mailtoui-brand a:hover{font-weight:700;outline:0}.mailtoui-no-scroll{overflow:hidden;position:fixed;width:100%}.mailtoui-is-hidden{display:none;visibility:hidden}@-webkit-keyframes mailtoui-appear{0%{opacity:0;-webkit-transform:translate(-50%,-50%) scale(0,0);transform:translate(-50%,-50%) scale(0,0)}100%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1,1);transform:translate(-50%,-50%) scale(1,1)}}@keyframes mailtoui-appear{0%{opacity:0;-webkit-transform:translate(-50%,-50%) scale(0,0);transform:translate(-50%,-50%) scale(0,0)}100%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1,1);transform:translate(-50%,-50%) scale(1,1)}}
|
|
@ -0,0 +1 @@
|
|||
<div class="mailtoui-modal-content"><div class="mailtoui-modal-head"><div id="mailtoui-modal-title" class="mailtoui-modal-title">${options.title}</div><a id="mailtoui-modal-close" class="mailtoui-modal-close" href="#">×</a></div><div class="mailtoui-modal-body"><div class="mailtoui-clients"><a id="mailtoui-button-1" class="mailtoui-button" href="#"><div class="mailtoui-button-content"><span id="mailtoui-button-icon-1" class="mailtoui-button-icon">${options.buttonIcon1}</span> <span id="mailtoui-button-text-1" class="mailtoui-button-text">${options.buttonText1}</span></div></a><a id="mailtoui-button-2" class="mailtoui-button" href="#"><div class="mailtoui-button-content"><span id="mailtoui-button-icon-2" class="mailtoui-button-icon">${options.buttonIcon2}</span> <span id="mailtoui-button-text-2" class="mailtoui-button-text">${options.buttonText2}</span></div></a><a id="mailtoui-button-3" class="mailtoui-button" href="#"><div class="mailtoui-button-content"><span id="mailtoui-button-icon-3" class="mailtoui-button-icon">${options.buttonIcon3}</span> <span id="mailtoui-button-text-3" class="mailtoui-button-text">${options.buttonText3}</span></div></a><a id="mailtoui-button-4" class="mailtoui-button" href="#"><div class="mailtoui-button-content"><span id="mailtoui-button-icon-4" class="mailtoui-button-icon">${options.buttonIcon4}</span> <span id="mailtoui-button-text-4" class="mailtoui-button-text">${options.buttonText4}</span></div></a></div><div id="mailtoui-copy" class="mailtoui-copy"><div id="mailtoui-email-address" class="mailtoui-email-address"></div><button id="mailtoui-button-copy" class="mailtoui-button-copy" data-copytargetid="mailtoui-email-address"><span id="mailtoui-button-icon-copy" class="mailtoui-button-icon">${options.buttonIconCopy}</span> <span id="mailtoui-button-text-copy" class="mailtoui-button-text">${options.buttonTextCopy}</span></button></div><div class="mailtoui-brand"><a href="https://mailtoui.com?ref=ui" target="_blank">Powered by MailtoUI</a></div></div></div>
|
|
@ -0,0 +1,49 @@
|
|||
<div class="mailtoui-modal-content">
|
||||
<div class="mailtoui-modal-head">
|
||||
<div id="mailtoui-modal-title" class="mailtoui-modal-title">${options.title}</div>
|
||||
<a id="mailtoui-modal-close" class="mailtoui-modal-close" href="#">×</a>
|
||||
</div>
|
||||
<div class="mailtoui-modal-body">
|
||||
<div class="mailtoui-clients">
|
||||
<a id="mailtoui-button-1" class="mailtoui-button" href="#">
|
||||
<div class="mailtoui-button-content">
|
||||
<span id="mailtoui-button-icon-1" class="mailtoui-button-icon">${options.buttonIcon1}</span>
|
||||
<span id="mailtoui-button-text-1" class="mailtoui-button-text">${options.buttonText1}</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a id="mailtoui-button-2" class="mailtoui-button" href="#">
|
||||
<div class="mailtoui-button-content">
|
||||
<span id="mailtoui-button-icon-2" class="mailtoui-button-icon">${options.buttonIcon2}</span>
|
||||
<span id="mailtoui-button-text-2" class="mailtoui-button-text">${options.buttonText2}</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a id="mailtoui-button-3" class="mailtoui-button" href="#">
|
||||
<div class="mailtoui-button-content">
|
||||
<span id="mailtoui-button-icon-3" class="mailtoui-button-icon">${options.buttonIcon3}</span>
|
||||
<span id="mailtoui-button-text-3" class="mailtoui-button-text">${options.buttonText3}</span>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a id="mailtoui-button-4" class="mailtoui-button" href="#">
|
||||
<div class="mailtoui-button-content">
|
||||
<span id="mailtoui-button-icon-4" class="mailtoui-button-icon">${options.buttonIcon4}</span>
|
||||
<span id="mailtoui-button-text-4" class="mailtoui-button-text">${options.buttonText4}</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div id="mailtoui-copy" class="mailtoui-copy">
|
||||
<div id="mailtoui-email-address" class="mailtoui-email-address"></div>
|
||||
<button id="mailtoui-button-copy" class="mailtoui-button-copy" data-copytargetid="mailtoui-email-address">
|
||||
<span id="mailtoui-button-icon-copy" class="mailtoui-button-icon">${options.buttonIconCopy}</span>
|
||||
<span id="mailtoui-button-text-copy" class="mailtoui-button-text">${options.buttonTextCopy}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="mailtoui-brand">
|
||||
<a href="https://mailtoui.com?ref=ui" target="_blank">Powered by MailtoUI</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
File diff suppressed because it is too large
Load Diff
281
src/mailgo.scss
281
src/mailgo.scss
|
@ -1,281 +0,0 @@
|
|||
$mailgo-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif,
|
||||
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
|
||||
// colors
|
||||
$default-color: #4a4a4a;
|
||||
$gmail-color: #c0372a;
|
||||
$outlook-color: #0967aa;
|
||||
$wa-color: #067466;
|
||||
$telegram-color: #086da0;
|
||||
$skype-color: #076d92;
|
||||
|
||||
$default-color-hover: #3d3d3d;
|
||||
|
||||
$default-dark-color: #eaeaea;
|
||||
$gmail-dark-color: #e07d73;
|
||||
$outlook-dark-color: #4c9cd7;
|
||||
$wa-dark-color: #4cd2c0;
|
||||
$telegram-dark-color: #4cabdb;
|
||||
$skype-dark-color: #4cc7f4;
|
||||
|
||||
// other vars
|
||||
$default-border-radius: 20px;
|
||||
|
||||
.m-modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
font-size: 16.5px;
|
||||
z-index: 10000;
|
||||
|
||||
p,
|
||||
span,
|
||||
strong,
|
||||
a {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 100%;
|
||||
line-height: 1;
|
||||
font-family: $mailgo-font-family;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.m-modal-back {
|
||||
position: absolute;
|
||||
z-index: 10001;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: #20232a;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.m-modal-content {
|
||||
position: relative;
|
||||
z-index: 10002;
|
||||
box-sizing: content-box;
|
||||
text-align: center;
|
||||
min-width: 200px;
|
||||
max-width: 240px;
|
||||
background-color: #fff;
|
||||
opacity: 0.95;
|
||||
border-radius: $default-border-radius;
|
||||
box-shadow: 0 3px 20px rgba(32, 35, 42, 0.5);
|
||||
color: $default-color;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
padding: 24px;
|
||||
transition: 0.5s box-shadow;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.m-title {
|
||||
margin-bottom: 8px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
|
||||
.m-details {
|
||||
margin-bottom: 10px;
|
||||
p {
|
||||
font-size: 12px;
|
||||
margin-top: 3px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
cursor: pointer;
|
||||
padding: 10px;
|
||||
color: $default-color;
|
||||
border-radius: $default-border-radius;
|
||||
text-decoration: none;
|
||||
|
||||
&.m-gmail {
|
||||
color: $gmail-color;
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: rgba(212, 70, 56, 0.08);
|
||||
color: $gmail-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.m-outlook {
|
||||
color: $outlook-color;
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: rgba(0, 114, 198, 0.08);
|
||||
color: $outlook-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.m-tg {
|
||||
color: $telegram-color;
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: rgba(0, 136, 204, 0.08);
|
||||
color: $telegram-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.m-wa {
|
||||
color: $wa-color;
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: rgba(0, 191, 165, 0.08);
|
||||
color: $wa-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.m-skype {
|
||||
color: $skype-color;
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: rgba(0, 175, 240, 0.08);
|
||||
color: $skype-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.m-copy {
|
||||
padding: 16px 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&.m-default,
|
||||
&.m-copy {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: rgba(0, 0, 0, 0.08);
|
||||
color: $default-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.m-by {
|
||||
font-size: 12px;
|
||||
margin-top: 0.8rem;
|
||||
padding: 5px;
|
||||
color: $default-color;
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
color: $default-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.w-500 {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
&.m-dark {
|
||||
.m-modal-content {
|
||||
background-color: #20232a;
|
||||
&,
|
||||
& p,
|
||||
& p span,
|
||||
& strong {
|
||||
color: #fff;
|
||||
}
|
||||
a {
|
||||
color: $default-dark-color;
|
||||
|
||||
&:not(.m-by) {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: rgba(134, 134, 134, 0.08);
|
||||
color: $default-dark-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.m-gmail {
|
||||
color: $gmail-dark-color;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: rgba(212, 70, 56, 0.08);
|
||||
color: $gmail-dark-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.m-outlook {
|
||||
color: $outlook-dark-color;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: rgba(0, 114, 198, 0.08);
|
||||
color: $outlook-dark-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.m-tg {
|
||||
color: $telegram-dark-color;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: rgba(0, 136, 204, 0.08);
|
||||
color: $telegram-dark-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.m-wa {
|
||||
color: $wa-dark-color;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: rgba(0, 191, 165, 0.08);
|
||||
color: $wa-dark-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.m-skype {
|
||||
color: $skype-dark-color;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: rgba(0, 175, 240, 0.08);
|
||||
color: $skype-dark-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.m-by {
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
990
src/mailgo.ts
990
src/mailgo.ts
|
@ -1,990 +0,0 @@
|
|||
import {
|
||||
MailgoConfig,
|
||||
MailgoTranslations,
|
||||
MailgoTranslation,
|
||||
MailgoI18n,
|
||||
} from "mailgo";
|
||||
|
||||
// i18n for mailgo
|
||||
const i18n: MailgoI18n = require("../i18n/i18n.json");
|
||||
|
||||
// mailgo scss
|
||||
const mailgoCSS: string = require("./mailgo.scss").toString();
|
||||
|
||||
// default lang
|
||||
const DEFAULT_LANG: string = "en";
|
||||
|
||||
// links
|
||||
const MAILTO: string = "mailto:";
|
||||
const TEL: string = "tel:";
|
||||
const CALLTO: string = "callto:";
|
||||
|
||||
// deep linking
|
||||
const outlookDeepLink: string = "ms-outlook://";
|
||||
|
||||
// mailgo types
|
||||
const MAIL_TYPE: string = "mail";
|
||||
const TEL_TYPE: string = "tel";
|
||||
|
||||
// default href for links
|
||||
const DEFAULT_BTN_HREF: string = "javascript:void(0);";
|
||||
|
||||
// useful html tags
|
||||
const spanHTMLTag: string = "span";
|
||||
const aHTMLTag: string = "a";
|
||||
const pHTMLTag: string = "p";
|
||||
|
||||
// global mailgo config object
|
||||
let config: MailgoConfig;
|
||||
|
||||
// default language
|
||||
let lang: string = DEFAULT_LANG;
|
||||
|
||||
// modals global object
|
||||
let modalMailto: HTMLElement, modalTel: HTMLElement;
|
||||
|
||||
// mailgo variables
|
||||
let url: URL,
|
||||
mail: string = "",
|
||||
encEmail: string = "",
|
||||
cc: string = "",
|
||||
bcc: string = "",
|
||||
subject: string = "",
|
||||
bodyMail: string = "";
|
||||
|
||||
// mailgo tel variables
|
||||
let tel: string = "",
|
||||
msg: string = "",
|
||||
skypeUsername: string = "";
|
||||
|
||||
// the DOM elements
|
||||
let title: HTMLElement,
|
||||
titleTel: HTMLElement,
|
||||
detailCc: HTMLElement,
|
||||
detailBcc: HTMLElement,
|
||||
detailSubject: HTMLElement,
|
||||
detailBody: HTMLElement,
|
||||
ccValue: HTMLElement,
|
||||
bccValue: HTMLElement,
|
||||
subjectValue: HTMLElement,
|
||||
bodyValue: HTMLElement,
|
||||
activatedLink: HTMLElement;
|
||||
|
||||
// mailgo buttons (actions)
|
||||
let gmail: HTMLLinkElement,
|
||||
outlook: HTMLLinkElement,
|
||||
open: HTMLLinkElement,
|
||||
wa: HTMLLinkElement,
|
||||
skype: HTMLLinkElement,
|
||||
call: HTMLLinkElement,
|
||||
copyMail: HTMLLinkElement,
|
||||
copyTel: HTMLLinkElement;
|
||||
|
||||
/**
|
||||
* mailgoInit
|
||||
* the function that creates the mailgo elements in DOM
|
||||
*/
|
||||
const mailgoInit = (): void => {
|
||||
// translations
|
||||
let {
|
||||
translations,
|
||||
}: { translations: MailgoTranslations } = i18n as MailgoI18n;
|
||||
|
||||
// if a default language is defined use it
|
||||
if (config?.lang && i18n.languages.indexOf(config.lang) !== -1) {
|
||||
lang = config.lang;
|
||||
}
|
||||
|
||||
// if is defined <html lang=""> use it!
|
||||
if (!config?.forceLang) {
|
||||
// keep the lang from html
|
||||
let htmlLang: string = document.documentElement.lang;
|
||||
|
||||
// if there are translations...
|
||||
if (i18n.languages.indexOf(htmlLang) !== -1) {
|
||||
lang = document.documentElement.lang;
|
||||
}
|
||||
}
|
||||
|
||||
// strings
|
||||
let defaultStrings: MailgoTranslation = translations[DEFAULT_LANG];
|
||||
let strings: MailgoTranslation = translations[lang];
|
||||
|
||||
// mailgo, if mailgo not already exists
|
||||
let mailgoExists = !!document.getElementById("mailgo");
|
||||
|
||||
if (!mailgoExists) {
|
||||
// modal
|
||||
modalMailto = createElement() as HTMLElement;
|
||||
modalMailto.style.display = "none";
|
||||
modalMailto.id = "mailgo";
|
||||
modalMailto.classList.add("m-modal");
|
||||
modalMailto.setAttribute("role", "dialog");
|
||||
modalMailto.setAttribute("tabindex", "-1");
|
||||
modalMailto.setAttribute("aria-labelledby", "m-title");
|
||||
|
||||
// if dark is in config
|
||||
if (config?.dark) {
|
||||
enableDarkMode(MAIL_TYPE);
|
||||
} else {
|
||||
disableDarkMode(MAIL_TYPE);
|
||||
}
|
||||
|
||||
// background
|
||||
let modalBackground: HTMLElement = createElement();
|
||||
modalBackground.className = "m-modal-back";
|
||||
modalMailto.appendChild(modalBackground);
|
||||
|
||||
// modal content
|
||||
let modalContent: HTMLElement = createElement();
|
||||
modalContent.className = "m-modal-content";
|
||||
modalMailto.appendChild(modalContent);
|
||||
|
||||
// title (email address)
|
||||
title = createElement("strong");
|
||||
title.id = "m-title";
|
||||
title.className = "m-title";
|
||||
modalContent.appendChild(title);
|
||||
|
||||
// details
|
||||
let details: HTMLElement = createElement();
|
||||
details.id = "m-details";
|
||||
details.className = "m-details";
|
||||
|
||||
detailCc = createElement(pHTMLTag);
|
||||
detailCc.id = "m-cc";
|
||||
let ccSpan: HTMLElement = createElement(spanHTMLTag);
|
||||
ccSpan.className = "w-500";
|
||||
ccSpan.appendChild(createTextNode(strings.cc_ || defaultStrings.cc_));
|
||||
ccValue = createElement(spanHTMLTag);
|
||||
ccValue.id = "m-cc-value";
|
||||
detailCc.appendChild(ccSpan);
|
||||
detailCc.appendChild(ccValue);
|
||||
details.appendChild(detailCc);
|
||||
|
||||
detailBcc = createElement(pHTMLTag);
|
||||
detailBcc.id = "m-bcc";
|
||||
let bccSpan: HTMLElement = createElement(spanHTMLTag);
|
||||
bccSpan.className = "w-500";
|
||||
bccSpan.appendChild(createTextNode(strings.bcc_ || defaultStrings.bcc_));
|
||||
bccValue = createElement(spanHTMLTag);
|
||||
bccValue.id = "m-bcc-value";
|
||||
detailBcc.appendChild(bccSpan);
|
||||
detailBcc.appendChild(bccValue);
|
||||
details.appendChild(detailBcc);
|
||||
|
||||
detailSubject = createElement(pHTMLTag);
|
||||
detailSubject.id = "m-subject";
|
||||
let subjectSpan: HTMLElement = createElement(spanHTMLTag);
|
||||
subjectSpan.className = "w-500";
|
||||
subjectSpan.appendChild(
|
||||
createTextNode(strings.subject_ || defaultStrings.subject_)
|
||||
);
|
||||
subjectValue = createElement(spanHTMLTag);
|
||||
subjectValue.id = "m-subject-value";
|
||||
detailSubject.appendChild(subjectSpan);
|
||||
detailSubject.appendChild(subjectValue);
|
||||
details.appendChild(detailSubject);
|
||||
|
||||
detailBody = createElement(pHTMLTag);
|
||||
detailBody.id = "m-body";
|
||||
let bodySpan: HTMLElement = createElement(spanHTMLTag);
|
||||
bodySpan.className = "w-500";
|
||||
bodySpan.appendChild(createTextNode(strings.body_ || defaultStrings.body_));
|
||||
bodyValue = createElement(spanHTMLTag);
|
||||
bodyValue.id = "m-body-value";
|
||||
detailBody.appendChild(bodySpan);
|
||||
detailBody.appendChild(bodyValue);
|
||||
details.appendChild(detailBody);
|
||||
|
||||
modalContent.appendChild(details);
|
||||
|
||||
// Gmail
|
||||
gmail = createElement(aHTMLTag) as HTMLLinkElement;
|
||||
gmail.id = "m-gmail";
|
||||
gmail.href = DEFAULT_BTN_HREF;
|
||||
gmail.classList.add("m-open");
|
||||
gmail.classList.add("m-gmail");
|
||||
gmail.appendChild(
|
||||
createTextNode(strings.open_in_ || defaultStrings.open_in_)
|
||||
);
|
||||
let gmailSpan: HTMLElement = createElement(spanHTMLTag);
|
||||
gmailSpan.className = "w-500";
|
||||
gmailSpan.appendChild(
|
||||
createTextNode(strings.gmail || defaultStrings.gmail)
|
||||
);
|
||||
gmail.appendChild(gmailSpan);
|
||||
|
||||
modalContent.appendChild(gmail);
|
||||
|
||||
// Outlook
|
||||
outlook = createElement(aHTMLTag) as HTMLLinkElement;
|
||||
outlook.id = "m-outlook";
|
||||
outlook.href = DEFAULT_BTN_HREF;
|
||||
outlook.classList.add("m-open");
|
||||
outlook.classList.add("m-outlook");
|
||||
outlook.appendChild(
|
||||
createTextNode(strings.open_in_ || defaultStrings.open_in_)
|
||||
);
|
||||
let outlookSpan: HTMLElement = createElement(spanHTMLTag);
|
||||
outlookSpan.className = "w-500";
|
||||
outlookSpan.appendChild(
|
||||
createTextNode(strings.outlook || defaultStrings.outlook)
|
||||
);
|
||||
outlook.appendChild(outlookSpan);
|
||||
|
||||
modalContent.appendChild(outlook);
|
||||
|
||||
// open default
|
||||
open = createElement(aHTMLTag) as HTMLLinkElement;
|
||||
open.id = "m-open";
|
||||
open.href = DEFAULT_BTN_HREF;
|
||||
open.classList.add("m-open");
|
||||
open.classList.add("m-default");
|
||||
let openSpan: HTMLElement = createElement(spanHTMLTag);
|
||||
openSpan.className = "w-500";
|
||||
openSpan.appendChild(createTextNode(strings.open || defaultStrings.open));
|
||||
open.appendChild(openSpan);
|
||||
open.appendChild(
|
||||
createTextNode(strings._default || defaultStrings._default)
|
||||
);
|
||||
|
||||
modalContent.appendChild(open);
|
||||
|
||||
// copy
|
||||
copyMail = createElement(aHTMLTag) as HTMLLinkElement;
|
||||
copyMail.id = "m-copy";
|
||||
copyMail.href = DEFAULT_BTN_HREF;
|
||||
copyMail.classList.add("m-copy");
|
||||
copyMail.classList.add("w-500");
|
||||
copyMail.appendChild(createTextNode(strings.copy || defaultStrings.copy));
|
||||
|
||||
modalContent.appendChild(copyMail);
|
||||
|
||||
// add the modal at the end of the body
|
||||
document.body.appendChild(modalMailto);
|
||||
|
||||
// every click outside the modal will hide the modal
|
||||
modalBackground.addEventListener("click", hideMailgo);
|
||||
}
|
||||
|
||||
// mailgo tel, if mailgo-tel not already exists
|
||||
let mailgoTelExists = !!document.getElementById("mailgo-tel");
|
||||
|
||||
if (!mailgoTelExists) {
|
||||
// modal
|
||||
modalTel = createElement() as HTMLElement;
|
||||
modalTel.style.display = "none";
|
||||
modalTel.id = "mailgo-tel";
|
||||
modalTel.classList.add("m-modal");
|
||||
modalTel.setAttribute("role", "dialog");
|
||||
modalTel.setAttribute("tabindex", "-1");
|
||||
modalTel.setAttribute("aria-labelledby", "m-tel-title");
|
||||
|
||||
// if dark is in config
|
||||
if (config?.dark) {
|
||||
enableDarkMode(TEL_TYPE);
|
||||
} else {
|
||||
disableDarkMode(TEL_TYPE);
|
||||
}
|
||||
|
||||
// background
|
||||
let modalBackground: HTMLElement = createElement();
|
||||
modalBackground.className = "m-modal-back";
|
||||
modalTel.appendChild(modalBackground);
|
||||
|
||||
// modal content
|
||||
let modalContent: HTMLElement = createElement();
|
||||
modalContent.className = "m-modal-content";
|
||||
modalTel.appendChild(modalContent);
|
||||
|
||||
// title (telephone number)
|
||||
titleTel = createElement("strong");
|
||||
titleTel.id = "m-tel-title";
|
||||
titleTel.className = "m-title";
|
||||
modalContent.appendChild(titleTel);
|
||||
|
||||
// WhatsApp
|
||||
wa = createElement(aHTMLTag) as HTMLLinkElement;
|
||||
wa.id = "m-wa";
|
||||
wa.href = DEFAULT_BTN_HREF;
|
||||
wa.classList.add("m-open");
|
||||
wa.classList.add("m-wa");
|
||||
wa.appendChild(createTextNode(strings.open_in_ || defaultStrings.open_in_));
|
||||
let waSpan: HTMLElement = createElement(spanHTMLTag);
|
||||
waSpan.className = "w-500";
|
||||
waSpan.appendChild(
|
||||
createTextNode(strings.whatsapp || defaultStrings.whatsapp)
|
||||
);
|
||||
wa.appendChild(waSpan);
|
||||
|
||||
modalContent.appendChild(wa);
|
||||
|
||||
// Skype
|
||||
skype = createElement(aHTMLTag) as HTMLLinkElement;
|
||||
skype.id = "m-skype";
|
||||
skype.href = DEFAULT_BTN_HREF;
|
||||
skype.classList.add("m-open");
|
||||
skype.classList.add("m-skype");
|
||||
skype.appendChild(
|
||||
createTextNode(strings.open_in_ || defaultStrings.open_in_)
|
||||
);
|
||||
let skypeSpan: HTMLElement = createElement(spanHTMLTag);
|
||||
skypeSpan.className = "w-500";
|
||||
skypeSpan.appendChild(
|
||||
createTextNode(strings.skype || defaultStrings.skype)
|
||||
);
|
||||
skype.appendChild(skypeSpan);
|
||||
|
||||
modalContent.appendChild(skype);
|
||||
|
||||
// call default
|
||||
call = createElement(aHTMLTag) as HTMLLinkElement;
|
||||
call.id = "m-call";
|
||||
call.href = DEFAULT_BTN_HREF;
|
||||
call.classList.add("m-open");
|
||||
call.classList.add("m-default");
|
||||
let callSpan: HTMLElement = createElement(spanHTMLTag);
|
||||
callSpan.className = "w-500";
|
||||
callSpan.appendChild(createTextNode(strings.call || defaultStrings.call));
|
||||
call.appendChild(callSpan);
|
||||
call.appendChild(
|
||||
createTextNode(strings._as_default || defaultStrings._as_default)
|
||||
);
|
||||
|
||||
modalContent.appendChild(call);
|
||||
|
||||
// copy
|
||||
copyTel = createElement(aHTMLTag) as HTMLLinkElement;
|
||||
copyTel.id = "m-tel-copy";
|
||||
copyTel.href = DEFAULT_BTN_HREF;
|
||||
copyTel.classList.add("m-copy");
|
||||
copyTel.classList.add("w-500");
|
||||
copyTel.appendChild(createTextNode(strings.copy || defaultStrings.copy));
|
||||
|
||||
modalContent.appendChild(copyTel);
|
||||
|
||||
// add the modal at the end of the body
|
||||
document.body.appendChild(modalTel);
|
||||
|
||||
// every click outside the modal will hide the modal
|
||||
modalBackground.addEventListener("click", hideMailgo);
|
||||
}
|
||||
|
||||
// event listener on body, if the element is mailgo-compatible the mailgo modal will be rendered
|
||||
document.addEventListener("click", mailgoCheckRender);
|
||||
};
|
||||
|
||||
/**
|
||||
* mailgoRender
|
||||
* function to render a mailgo (mail or tel)
|
||||
*/
|
||||
export function mailgoRender(
|
||||
type: string = MAIL_TYPE,
|
||||
mailgoElement: HTMLLinkElement
|
||||
): void {
|
||||
// mailgo mail
|
||||
if (type === MAIL_TYPE) {
|
||||
// if the element href=^"mailto:"
|
||||
if (
|
||||
mailgoElement.href &&
|
||||
mailgoElement.href.toLowerCase().startsWith(MAILTO)
|
||||
) {
|
||||
mail = decodeURIComponent(
|
||||
mailgoElement.href.split("?")[0].split(MAILTO)[1].trim()
|
||||
);
|
||||
|
||||
url = new URL(mailgoElement.href);
|
||||
let urlParams: URLSearchParams = url.searchParams;
|
||||
|
||||
// optional parameters for the email
|
||||
cc = urlParams.get("cc");
|
||||
bcc = urlParams.get("bcc");
|
||||
subject = urlParams.get("subject");
|
||||
bodyMail = urlParams.get("body");
|
||||
} else {
|
||||
// if the element href="#mailgo" or class="mailgo"
|
||||
// mail = data-address + @ + data-domain
|
||||
mail =
|
||||
mailgoElement.getAttribute("data-address") +
|
||||
"@" +
|
||||
mailgoElement.getAttribute("data-domain");
|
||||
|
||||
url = new URL(MAILTO + encodeURIComponent(mail));
|
||||
|
||||
// cc = data-cc-address + @ + data-cc-domain
|
||||
cc =
|
||||
mailgoElement.getAttribute("data-cc-address") +
|
||||
"@" +
|
||||
mailgoElement.getAttribute("data-cc-domain");
|
||||
|
||||
// bcc = data-bcc-address + @ + data-bcc-domain
|
||||
bcc =
|
||||
mailgoElement.getAttribute("data-bcc-address") +
|
||||
"@" +
|
||||
mailgoElement.getAttribute("data-bcc-domain");
|
||||
|
||||
// subject = data-subject
|
||||
subject = mailgoElement.getAttribute("data-subject");
|
||||
|
||||
// body = data-body
|
||||
bodyMail = mailgoElement.getAttribute("data-body");
|
||||
}
|
||||
|
||||
if (
|
||||
typeof config?.validateEmail === "undefined" ||
|
||||
config?.validateEmail === true
|
||||
) {
|
||||
// validate the email address
|
||||
if (!validateEmails(mail.split(","))) return;
|
||||
|
||||
// if cc, bcc are not valid cc, bcc = ""
|
||||
if (cc && !validateEmails(cc.split(","))) cc = "";
|
||||
if (bcc && !validateEmails(bcc.split(","))) bcc = "";
|
||||
}
|
||||
|
||||
// the title of the modal (email address)
|
||||
title.innerHTML = mail.split(",").join("<br/>");
|
||||
|
||||
// add the details if provided
|
||||
cc
|
||||
? ((detailCc.style.display = "block"),
|
||||
(ccValue.innerHTML = cc.split(",").join("<br/>")))
|
||||
: (detailCc.style.display = "none");
|
||||
|
||||
bcc
|
||||
? ((detailBcc.style.display = "block"),
|
||||
(bccValue.innerHTML = bcc.split(",").join("<br/>")))
|
||||
: (detailBcc.style.display = "none");
|
||||
|
||||
subject
|
||||
? ((detailSubject.style.display = "block"),
|
||||
(subjectValue.textContent = subject))
|
||||
: (detailSubject.style.display = "none");
|
||||
|
||||
bodyMail
|
||||
? ((detailBody.style.display = "block"),
|
||||
(bodyValue.textContent = bodyMail))
|
||||
: (detailBody.style.display = "none");
|
||||
|
||||
// add the actions
|
||||
gmail.addEventListener("click", openGmail);
|
||||
|
||||
outlook.addEventListener("click", openOutlook);
|
||||
|
||||
encEmail = encodeEmail(mail);
|
||||
open.addEventListener("click", openDefault);
|
||||
|
||||
copyMail.addEventListener("click", () => copy(mail));
|
||||
}
|
||||
// mailgo tel
|
||||
else if (type === TEL_TYPE) {
|
||||
if (
|
||||
mailgoElement.href &&
|
||||
mailgoElement.href.toLowerCase().startsWith(TEL)
|
||||
) {
|
||||
tel = decodeURIComponent(
|
||||
mailgoElement.href.split("?")[0].split(TEL)[1].trim()
|
||||
);
|
||||
} else if (
|
||||
mailgoElement.href &&
|
||||
mailgoElement.href.toLowerCase().startsWith(CALLTO)
|
||||
) {
|
||||
tel = decodeURIComponent(
|
||||
mailgoElement.href.split("?")[0].split(CALLTO)[1].trim()
|
||||
);
|
||||
} else if (mailgoElement.hasAttribute("data-tel")) {
|
||||
tel = mailgoElement.getAttribute("data-tel");
|
||||
msg = mailgoElement.getAttribute("data-msg");
|
||||
}
|
||||
|
||||
// validate the phone number
|
||||
if (!validateTel(tel)) return;
|
||||
|
||||
if (mailgoElement.hasAttribute("data-skype")) {
|
||||
skypeUsername = mailgoElement.getAttribute("data-skype");
|
||||
}
|
||||
|
||||
// the title of the modal (tel)
|
||||
titleTel.innerHTML = tel;
|
||||
|
||||
// add the actions to buttons
|
||||
wa.addEventListener("click", openWhatsApp);
|
||||
|
||||
skype.addEventListener("click", openSkype);
|
||||
|
||||
call.addEventListener("click", callDefault);
|
||||
|
||||
copyTel.addEventListener("click", () => copy(tel));
|
||||
}
|
||||
|
||||
// if config.dark is set to true then all the modals will be in dark mode
|
||||
if (!config?.dark) {
|
||||
// if the element contains dark as class enable dark mode
|
||||
if (mailgoElement.classList.contains("dark")) {
|
||||
enableDarkMode(type);
|
||||
} else {
|
||||
disableDarkMode(type);
|
||||
}
|
||||
}
|
||||
|
||||
// show the mailgo
|
||||
showMailgo(type);
|
||||
|
||||
// add listener keyDown
|
||||
document.addEventListener("keydown", mailgoKeydown);
|
||||
}
|
||||
|
||||
// actions
|
||||
const openGmail = (): void => {
|
||||
// Gmail url
|
||||
let gmailUrl: string =
|
||||
"https://mail.google.com/mail/u/0/?view=cm&source=mailto&to=" +
|
||||
encodeURIComponent(mail);
|
||||
|
||||
// the details if provided
|
||||
if (cc) gmailUrl = gmailUrl.concat("&cc=" + encodeURIComponent(cc));
|
||||
if (bcc) gmailUrl = gmailUrl.concat("&bcc=" + encodeURIComponent(bcc));
|
||||
if (subject) gmailUrl = gmailUrl.concat("&subject=" + subject);
|
||||
if (bodyMail) gmailUrl = gmailUrl.concat("&body=" + bodyMail);
|
||||
|
||||
// open the link
|
||||
window.open(gmailUrl, "_blank");
|
||||
|
||||
// hide the modal
|
||||
hideMailgo();
|
||||
};
|
||||
|
||||
const openOutlook = (): void => {
|
||||
// Outlook url
|
||||
let outlookUrl: string =
|
||||
"https://outlook.live.com/owa/?path=/mail/action/compose&to=" +
|
||||
encodeURIComponent(mail);
|
||||
|
||||
// the details if provided
|
||||
if (subject) outlookUrl = outlookUrl.concat("&subject=" + subject);
|
||||
if (bodyMail) outlookUrl = outlookUrl.concat("&body=" + bodyMail);
|
||||
|
||||
// open the link
|
||||
window.open(outlookUrl, "_blank");
|
||||
|
||||
// hide the modal
|
||||
hideMailgo();
|
||||
};
|
||||
|
||||
const openDefault = (): void => {
|
||||
mailToEncoded(encEmail);
|
||||
hideMailgo();
|
||||
};
|
||||
|
||||
|
||||
const openSkype = (): void => {
|
||||
let skype: string = skypeUsername !== "" ? skypeUsername : tel;
|
||||
let skypeUrl: string = "skype:" + skype;
|
||||
|
||||
// open the url
|
||||
window.open(skypeUrl, "_blank");
|
||||
|
||||
// hide the modal
|
||||
hideMailgo();
|
||||
};
|
||||
|
||||
const openWhatsApp = (): void => {
|
||||
// WhatsApp url
|
||||
let waUrl: string = "https://wa.me/" + tel;
|
||||
|
||||
// the details if provided
|
||||
if (msg) waUrl + "?text=" + msg;
|
||||
|
||||
// open the url
|
||||
window.open(waUrl, "_blank");
|
||||
|
||||
// hide the modal
|
||||
hideMailgo();
|
||||
};
|
||||
|
||||
const callDefault = () => {
|
||||
let callUrl: string = "tel:" + tel;
|
||||
window.open(callUrl);
|
||||
hideMailgo();
|
||||
};
|
||||
|
||||
const copy = (content: string): void => {
|
||||
copyToClipboard(content);
|
||||
let activeCopy: HTMLElement;
|
||||
// the correct copyButton (mail or tel)
|
||||
mailgoIsShowing(MAIL_TYPE) ? (activeCopy = copyMail) : (activeCopy = copyTel);
|
||||
activeCopy.textContent = "kopiert";
|
||||
setTimeout(() => {
|
||||
activeCopy.textContent = "copy";
|
||||
// hide after the timeout
|
||||
hideMailgo();
|
||||
}, 999);
|
||||
};
|
||||
|
||||
// function that returns if an element is a mailgo
|
||||
export function isMailgo(
|
||||
element: HTMLElement,
|
||||
type: string = MAIL_TYPE
|
||||
): boolean {
|
||||
let href: string = (element as HTMLLinkElement).href;
|
||||
|
||||
// mailgo type mail
|
||||
if (type === MAIL_TYPE) {
|
||||
return (
|
||||
// first case: it is an <a> element with "mailto:..." in href and no no-mailgo in classList
|
||||
(href &&
|
||||
href.toLowerCase().startsWith(MAILTO) &&
|
||||
!element.classList.contains("no-mailgo")) ||
|
||||
(element.hasAttribute("data-address") &&
|
||||
// second case: the href=#mailgo
|
||||
((href && element.getAttribute("href").toLowerCase() === "#mailgo") ||
|
||||
// third case: the classList contains mailgo
|
||||
(element.classList && element.classList.contains("mailgo"))))
|
||||
);
|
||||
}
|
||||
|
||||
// mailgo type tel
|
||||
if (type === TEL_TYPE) {
|
||||
return (
|
||||
// first case: it is an <a> element with "tel:..." or "callto:..." in href and no no-mailgo in classList
|
||||
(href &&
|
||||
(href.toLowerCase().startsWith(TEL) ||
|
||||
href.toLowerCase().startsWith(CALLTO)) &&
|
||||
!element.classList.contains("no-mailgo")) ||
|
||||
(element.hasAttribute("data-tel") &&
|
||||
// second case: the href=#mailgo
|
||||
href &&
|
||||
element.getAttribute("href").toLowerCase() === "#mailgo") ||
|
||||
// third case: the classList contains mailgo
|
||||
(element.classList && element.classList.contains("mailgo"))
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* mailgoCheckRender
|
||||
* function to check if an element is mailgo-enabled or not referencing to
|
||||
* mail:
|
||||
* document.querySelectorAll(
|
||||
* 'a[href^="mailto:" i]:not(.no-mailgo), a[href="#mailgo"], a.mailgo'
|
||||
* );
|
||||
* tel:
|
||||
* document.querySelectorAll(
|
||||
* 'a[href^="tel:" i]:not(.no-mailgo), a[href="#mailgo"], a.mailgo'
|
||||
* );
|
||||
* or
|
||||
* document.querySelectorAll(
|
||||
* 'a[href^="callto:" i]:not(.no-mailgo), a[href="#mailgo"], a.mailgo'
|
||||
* );
|
||||
*/
|
||||
export function mailgoCheckRender(event: Event): boolean {
|
||||
// check if the id=mailgo exists in the body
|
||||
if (!document.contains(modalMailto) || !document.contains(modalTel))
|
||||
return false;
|
||||
|
||||
// if a mailgo is already showing do nothing
|
||||
if (mailgoIsShowing(MAIL_TYPE) || mailgoIsShowing(TEL_TYPE)) return false;
|
||||
|
||||
// the path of the event
|
||||
let path =
|
||||
(event.composedPath && event.composedPath()) ||
|
||||
composedPath(event.target as HTMLElement);
|
||||
|
||||
if (path) {
|
||||
path.forEach((element: HTMLElement) => {
|
||||
if (element instanceof HTMLDocument || element instanceof Window)
|
||||
return false;
|
||||
|
||||
// go in the event.path to find if the user has clicked on a mailgo element
|
||||
if (isMailgo(element, MAIL_TYPE)) {
|
||||
// stop the normal execution of the element click
|
||||
event.preventDefault();
|
||||
|
||||
// render mailgo
|
||||
mailgoRender(MAIL_TYPE, element as HTMLLinkElement);
|
||||
|
||||
return true;
|
||||
}
|
||||
if (isMailgo(element, TEL_TYPE)) {
|
||||
// stop the normal execution of the element click
|
||||
event.preventDefault();
|
||||
|
||||
// render mailgo
|
||||
mailgoRender(TEL_TYPE, element as HTMLLinkElement);
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* mailgoKeydown
|
||||
* function to manage the keydown event when the modal is showing
|
||||
*/
|
||||
const mailgoKeydown = (keyboardEvent: KeyboardEvent): void => {
|
||||
// if mailgo is showing
|
||||
if (mailgoIsShowing(MAIL_TYPE)) {
|
||||
switch (keyboardEvent.keyCode) {
|
||||
case 27:
|
||||
// Escape
|
||||
hideMailgo();
|
||||
break;
|
||||
case 71:
|
||||
// g -> open GMail
|
||||
openGmail();
|
||||
break;
|
||||
case 79:
|
||||
// o -> open Outlook
|
||||
openOutlook();
|
||||
break;
|
||||
case 32:
|
||||
case 13:
|
||||
// spacebar or enter -> open default
|
||||
openDefault();
|
||||
break;
|
||||
case 67:
|
||||
// c -> copy
|
||||
copy(mail);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
} else if (mailgoIsShowing(TEL_TYPE)) {
|
||||
switch (keyboardEvent.keyCode) {
|
||||
case 27:
|
||||
// Escape
|
||||
hideMailgo();
|
||||
break;
|
||||
case 87:
|
||||
// w -> open WhatsApp
|
||||
openWhatsApp();
|
||||
break;
|
||||
case 32:
|
||||
case 13:
|
||||
// spacebar or enter -> call default
|
||||
callDefault();
|
||||
break;
|
||||
case 67:
|
||||
// c -> copy
|
||||
copy(tel);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
// show the modal
|
||||
const showMailgo = (type = MAIL_TYPE): void => {
|
||||
// show the correct modal
|
||||
setModalDisplay(type, "flex");
|
||||
};
|
||||
|
||||
// hide the modal
|
||||
const hideMailgo = (): void => {
|
||||
// hide all the modals
|
||||
setModalDisplay(MAIL_TYPE, "none");
|
||||
setModalDisplay(TEL_TYPE, "none");
|
||||
|
||||
// remove listener keyDown
|
||||
document.removeEventListener("keydown", mailgoKeydown);
|
||||
};
|
||||
|
||||
// is the mailgo modal hidden?
|
||||
const mailgoIsShowing = (type = MAIL_TYPE): boolean => {
|
||||
return getModalDisplay(type) === "flex";
|
||||
};
|
||||
|
||||
// create element
|
||||
const createElement = (element: string = "div"): HTMLElement =>
|
||||
document.createElement(element);
|
||||
|
||||
// create text node
|
||||
const createTextNode = (element: string): Text =>
|
||||
document.createTextNode(element);
|
||||
|
||||
// decrypt email
|
||||
const mailToEncoded = (encoded: string): string =>
|
||||
(window.location.href = MAILTO + atob(encoded));
|
||||
|
||||
// encode email
|
||||
const encodeEmail = (email: string): string => btoa(email);
|
||||
|
||||
// get the correct HTMLElement from a type
|
||||
const getModalHTMLElement = (type: string = MAIL_TYPE) =>
|
||||
type === TEL_TYPE ? modalTel : modalMailto;
|
||||
|
||||
// get display value
|
||||
const getModalDisplay = (ref: string = MAIL_TYPE): string =>
|
||||
getModalHTMLElement(ref).style.display;
|
||||
|
||||
// set display value
|
||||
const setModalDisplay = (ref: string = MAIL_TYPE, value: string): void => {
|
||||
let modal = getModalHTMLElement(ref);
|
||||
modal.style.display = value;
|
||||
|
||||
if (value === "flex") {
|
||||
// "save" the activated link.
|
||||
activatedLink = document.activeElement as HTMLElement;
|
||||
modal.setAttribute("aria-hidden", "false");
|
||||
|
||||
// Focus on the modal container.
|
||||
modal.setAttribute("tabindex", "0");
|
||||
modal.focus();
|
||||
setFocusLoop(modal);
|
||||
} else {
|
||||
modal.setAttribute("aria-hidden", "true");
|
||||
|
||||
// focus back the activated link for getting back to the context.
|
||||
modal.setAttribute("tabindex", "-1");
|
||||
activatedLink.focus();
|
||||
}
|
||||
};
|
||||
|
||||
// set focus loop within modal
|
||||
const setFocusLoop = (ref: HTMLElement): void => {
|
||||
let modal = ref;
|
||||
modal
|
||||
.querySelector(".m-modal-content a:last-of-type")
|
||||
.addEventListener("keydown", leaveLastLink);
|
||||
modal
|
||||
.querySelector(".m-modal-content a:first-of-type")
|
||||
.addEventListener("keydown", leaveFirstLink);
|
||||
};
|
||||
|
||||
const leaveLastLink = (e: KeyboardEvent): void => {
|
||||
// going back to the first link to force looping
|
||||
if (e.code === "Tab" && e.shiftKey === false) {
|
||||
e.preventDefault();
|
||||
|
||||
((e.target as HTMLElement)
|
||||
.closest("div")
|
||||
.querySelector("a:first-of-type") as HTMLElement).focus();
|
||||
}
|
||||
};
|
||||
|
||||
const leaveFirstLink = (e: KeyboardEvent): void => {
|
||||
// going back to the first link to force looping
|
||||
if (e.code === "Tab" && e.shiftKey === true) {
|
||||
e.preventDefault();
|
||||
((e.target as HTMLElement)
|
||||
.closest("div")
|
||||
.querySelector("a:last-of-type") as HTMLElement).focus();
|
||||
}
|
||||
};
|
||||
|
||||
// enable dark mode
|
||||
const enableDarkMode = (type: string = MAIL_TYPE) =>
|
||||
getModalHTMLElement(type).classList.add("m-dark");
|
||||
|
||||
// disable dark mode
|
||||
const disableDarkMode = (type: string = MAIL_TYPE) =>
|
||||
getModalHTMLElement(type).classList.remove("m-dark");
|
||||
|
||||
// custom composedPath if path or event.composedPath() are not defined
|
||||
const composedPath = (
|
||||
el: HTMLElement
|
||||
): (HTMLElement | Document | (Window & typeof globalThis))[] => {
|
||||
let path = [];
|
||||
|
||||
while (el) {
|
||||
path.push(el);
|
||||
|
||||
if (el.tagName === "HTML") {
|
||||
path.push(document);
|
||||
path.push(window);
|
||||
return path;
|
||||
}
|
||||
|
||||
el = el.parentElement;
|
||||
}
|
||||
};
|
||||
|
||||
// validate a single email with regex
|
||||
const validateEmail = (email: string): boolean =>
|
||||
/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
|
||||
email
|
||||
);
|
||||
|
||||
// validate an array of emails
|
||||
const validateEmails = (arr: string[]): boolean => arr.every(validateEmail);
|
||||
|
||||
// validate a single tel with regex
|
||||
const validateTel = (tel: string): boolean =>
|
||||
/^[+]{0,1}[\s0-9]{0,}[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$/.test(tel);
|
||||
|
||||
// copy of a string
|
||||
const copyToClipboard = (str: string): boolean => {
|
||||
let el: HTMLInputElement = createElement("textarea") as HTMLInputElement;
|
||||
el.value = str;
|
||||
el.setAttribute("readonly", "");
|
||||
el.style.position = "absolute";
|
||||
el.style.left = "-9999px";
|
||||
document.body.appendChild(el);
|
||||
let selected: Range | boolean =
|
||||
document.getSelection().rangeCount > 0
|
||||
? document.getSelection().getRangeAt(0)
|
||||
: false;
|
||||
el.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(el);
|
||||
if (selected) {
|
||||
document.getSelection().removeAllRanges();
|
||||
document.getSelection().addRange(selected);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const mailgoStyle = (): void => {
|
||||
// mailgo style
|
||||
let mailgoCSSElement: HTMLStyleElement = createElement(
|
||||
"style"
|
||||
) as HTMLStyleElement;
|
||||
mailgoCSSElement.id = "mailgo-style";
|
||||
mailgoCSSElement.type = "text/css";
|
||||
mailgoCSSElement.appendChild(createTextNode(mailgoCSS));
|
||||
document.head.appendChild(mailgoCSSElement);
|
||||
};
|
||||
|
||||
// mailgo
|
||||
function mailgo(mailgoConfig?: MailgoConfig): void {
|
||||
// set the global config merging window mailgConfig and mailgoConfig passed as a parameter
|
||||
config = { ...mailgoConfig, ...((window as any)?.mailgoConfig || null) };
|
||||
|
||||
// if the window is defined...
|
||||
if (window && typeof window !== "undefined") {
|
||||
// add the style for mailgo
|
||||
mailgoStyle();
|
||||
|
||||
// if is set an initEvent add the listener
|
||||
if (config?.initEvent) {
|
||||
if (config?.listenerOptions) {
|
||||
// listener options specified
|
||||
document.addEventListener(
|
||||
config.initEvent,
|
||||
() => {
|
||||
mailgoInit();
|
||||
},
|
||||
config.listenerOptions
|
||||
);
|
||||
} else {
|
||||
// no listener options
|
||||
document.addEventListener(config.initEvent, () => {
|
||||
mailgoInit();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
mailgoInit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default mailgo;
|
|
@ -0,0 +1,305 @@
|
|||
$animation-speed: 0.4s; //0.4s
|
||||
$overlay-bg-color: rgba(0, 0, 0, 0.4); //rgba(0, 0, 0, 0.4)
|
||||
$radius: 8px; //8px
|
||||
$success-bg-color: #1f9d55; //#1f9d55
|
||||
$success-color: #fff; //#fff
|
||||
|
||||
$modal-border-radius: $radius; //$radius
|
||||
$modal-box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); //0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)
|
||||
|
||||
$modal-head-bg-color: #fff; //#fff
|
||||
$modal-head-padding-x: 20px; //20px
|
||||
$modal-head-padding-y: 10px; //10px
|
||||
|
||||
$modal-title-color: #303131; //#303131
|
||||
$modal-title-font-family: sans-serif; //sans-serif
|
||||
$modal-title-font-size: 120%; //120%
|
||||
$modal-title-font-weight: 700; //700
|
||||
|
||||
$modal-close-color-1: #aaa; //#aaa
|
||||
$modal-close-color-2: #000; //#000
|
||||
$modal-close-font-size: 38px; //38px
|
||||
$modal-close-top: -4px; //-4px
|
||||
|
||||
$modal-content-bg-color: #f1f5f8; //#f1f5f8
|
||||
$modal-body-padding: 20px; //20px
|
||||
|
||||
$button-bg-color: #fff; //#fff
|
||||
$button-border-radius: $radius; //$radius
|
||||
$button-border: none; //none
|
||||
$button-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.18); //0 2px 4px rgba(0, 0, 0, 0.18)
|
||||
$button-color: #333; //#333
|
||||
$button-margin-bottom: 20px; //20px
|
||||
$button-hover-bg-color: #555; //#555
|
||||
$button-hover-color: #fff; //#fff
|
||||
$button-padding-x: 20px; //20px
|
||||
$button-padding-y: 15px; //15px
|
||||
|
||||
$button-icon-height: 24px; //24px
|
||||
$button-icon-top: 4px; //4px
|
||||
$button-icon-width: 24px; //24px
|
||||
|
||||
$button-copy-border: $button-border; //$button-border
|
||||
|
||||
$email-bg-color: #d8dcdf; //#d8dcdf
|
||||
$email-box-shadow: unset; //unset
|
||||
$email-color: #48494a; //#48494a
|
||||
$email-margin-top: 20px; //20px
|
||||
|
||||
$brand-color: #888; //#888
|
||||
$brand-font-size: 80%; //80%
|
||||
|
||||
.mailtoui-modal {
|
||||
background-color: #000;
|
||||
background-color: $overlay-bg-color;
|
||||
bottom: 0;
|
||||
color: #303131;
|
||||
display: none;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.mailtoui-modal-content {
|
||||
animation: mailtoui-appear $animation-speed;
|
||||
background-color: $modal-content-bg-color;
|
||||
border-radius: $modal-border-radius;
|
||||
bottom: auto;
|
||||
box-shadow: $modal-box-shadow;
|
||||
left: 50%;
|
||||
max-height: calc(100% - 100px);
|
||||
overflow: auto;
|
||||
padding: 0;
|
||||
position: fixed;
|
||||
right: -45%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.mailtoui-modal-content:focus,
|
||||
.mailtoui-modal-content:hover {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
.mailtoui-modal-content {
|
||||
right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.mailtoui-modal-head {
|
||||
align-items: center;
|
||||
background-color: $modal-head-bg-color;
|
||||
clear: both;
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
padding: $modal-head-padding-y $modal-head-padding-x;
|
||||
}
|
||||
|
||||
.mailtoui-modal-title {
|
||||
color: $modal-title-color;
|
||||
flex: 1;
|
||||
font-family: $modal-title-font-family;
|
||||
font-size: $modal-title-font-size;
|
||||
font-weight: $modal-title-font-weight;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mailtoui-modal-close {
|
||||
color: $modal-close-color-1;
|
||||
flex: initial;
|
||||
font-size: $modal-close-font-size;
|
||||
margin-left: 20px;
|
||||
position: relative;
|
||||
text-align: right;
|
||||
text-decoration: none;
|
||||
top: $modal-close-top;
|
||||
}
|
||||
|
||||
.mailtoui-modal-close:focus,
|
||||
.mailtoui-modal-close:hover {
|
||||
color: $modal-close-color-2;
|
||||
cursor: pointer;
|
||||
font-weight: 700;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.mailtoui-modal-body {
|
||||
height: 100%;
|
||||
padding: $modal-body-padding;
|
||||
}
|
||||
|
||||
.mailtoui-button {
|
||||
color: $button-color;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.mailtoui-button:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.mailtoui-button:focus .mailtoui-button-content {
|
||||
background-color: #555;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.mailtoui-button-content {
|
||||
background-color: $button-bg-color;
|
||||
border: $button-border;
|
||||
border-radius: $button-border-radius;
|
||||
box-shadow: $button-box-shadow;
|
||||
margin-bottom: $button-margin-bottom;
|
||||
overflow: hidden;
|
||||
padding: $button-padding-y $button-padding-x;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mailtoui-button-content:hover {
|
||||
background-color: $button-hover-bg-color;
|
||||
color: $button-hover-color;
|
||||
}
|
||||
|
||||
.mailtoui-button:last-child .mailtoui-button-content {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.mailtoui-button-icon {
|
||||
display: inline-block;
|
||||
font-weight: 700;
|
||||
position: relative;
|
||||
top: $button-icon-top;
|
||||
}
|
||||
|
||||
.mailtoui-button-icon svg {
|
||||
height: $button-icon-height;
|
||||
width: $button-icon-width;
|
||||
}
|
||||
|
||||
.mailtoui-button-text {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.mailtoui-copy {
|
||||
border-radius: $button-border-radius;
|
||||
box-shadow: $button-box-shadow;
|
||||
height: 59px;
|
||||
margin-top: $email-margin-top;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mailtoui-button-copy {
|
||||
background-color: $button-bg-color;
|
||||
border: $button-copy-border;
|
||||
border-bottom-left-radius: $button-border-radius;
|
||||
border-top-left-radius: $button-border-radius;
|
||||
bottom: 21px;
|
||||
color: $button-color;
|
||||
font-size: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
padding: 15px 20px;
|
||||
position: absolute;
|
||||
text-overflow: ellipsis;
|
||||
top: 0;
|
||||
white-space: nowrap;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.mailtoui-button-copy:focus,
|
||||
.mailtoui-button-copy:hover {
|
||||
background-color: $button-hover-bg-color;
|
||||
color: $button-hover-color;
|
||||
cursor: pointer;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.mailtoui-button-copy-clicked,
|
||||
.mailtoui-button-copy-clicked:focus,
|
||||
.mailtoui-button-copy-clicked:hover {
|
||||
background-color: $success-bg-color;
|
||||
color: $success-color;
|
||||
}
|
||||
|
||||
.mailtoui-button-copy-clicked .mailtoui-button-icon,
|
||||
.mailtoui-button-copy-clicked:focus .mailtoui-button-icon,
|
||||
.mailtoui-button-copy-clicked:hover .mailtoui-button-icon {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.mailtoui-button-copy-clicked .mailtoui-button-text,
|
||||
.mailtoui-button-copy-clicked:focus .mailtoui-button-text,
|
||||
.mailtoui-button-copy-clicked:hover .mailtoui-button-text {
|
||||
color: #fff;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.mailtoui-email-address {
|
||||
background-color: $email-bg-color;
|
||||
border: none;
|
||||
border-radius: $button-border-radius;
|
||||
box-shadow: $email-box-shadow;
|
||||
box-sizing: border-box;
|
||||
color: $email-color;
|
||||
font-size: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
padding: 20px 20px 20px 140px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mailtoui-brand {
|
||||
color: $brand-color;
|
||||
font-size: $brand-font-size;
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mailtoui-brand a {
|
||||
color: $brand-color;
|
||||
}
|
||||
|
||||
.mailtoui-brand a:focus,
|
||||
.mailtoui-brand a:hover {
|
||||
font-weight: 700;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.mailtoui-no-scroll {
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mailtoui-is-hidden {
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
@keyframes mailtoui-appear {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -50%) scale(0, 0);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, -50%) scale(1, 1);
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/",
|
||||
"sourceMap": true,
|
||||
"noImplicitAny": true,
|
||||
"module": "ES6",
|
||||
"target": "ES6",
|
||||
"jsx": "react",
|
||||
"allowJs": true,
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"declaration": true
|
||||
},
|
||||
"include": [
|
||||
"mailgo.d.ts",
|
||||
"src",
|
||||
"webpack/mailgo.dist.ts"
|
||||
]
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
const path = require('path');
|
||||
|
||||
const mailgoRules = [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
include: path.resolve(__dirname, './src/'),
|
||||
use: [ 'babel-loader' ],
|
||||
exclude: /node_modules/
|
||||
},
|
||||
{
|
||||
test: /\.scss$/i,
|
||||
use: [
|
||||
'to-string-loader',
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
esModule: false,
|
||||
sourceMap: false
|
||||
}
|
||||
},
|
||||
'sass-loader'
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
mode: 'production',
|
||||
target: 'web',
|
||||
entry: './mailgo.dist.ts',
|
||||
context: path.join(__dirname, 'webpack'),
|
||||
module: {
|
||||
rules: mailgoRules
|
||||
},
|
||||
resolve: {
|
||||
extensions: [ '.ts', '.js' ]
|
||||
},
|
||||
output: {
|
||||
filename: 'mailgo.min.js',
|
||||
library: 'mailgo',
|
||||
libraryTarget: 'window',
|
||||
path: path.resolve(__dirname, 'dist')
|
||||
}
|
||||
}
|
||||
];
|
|
@ -1,8 +0,0 @@
|
|||
import mailgo from '../src/mailgo';
|
||||
|
||||
// call init mailgo attached to the event DOMContentLoaded
|
||||
const mailgoConfig = {
|
||||
initEvent: 'DOMContentLoaded'
|
||||
};
|
||||
|
||||
mailgo(mailgoConfig);
|
|
@ -1,2 +0,0 @@
|
|||
import mailgo from '../src/mailgo';
|
||||
export default mailgo;
|
Loading…
Reference in New Issue