mirror of
https://github.com/status-im/consul.git
synced 2025-02-21 09:58:26 +00:00
ui: Use native clipboard functionality, but keep fallback
This commit is contained in:
parent
499250cbf1
commit
22650621f2
16
ui/packages/consul-ui/app/initializers/clipboard.js
Normal file
16
ui/packages/consul-ui/app/initializers/clipboard.js
Normal file
@ -0,0 +1,16 @@
|
||||
import NavigatorClipboard from 'consul-ui/services/clipboard/native';
|
||||
import ExecClipboard from 'consul-ui/services/clipboard/polyfill';
|
||||
|
||||
export function initialize(application) {
|
||||
// which clipboard impl. depends on whether we have native support
|
||||
if (!application.hasRegistration('service:clipboard')) {
|
||||
application.register(
|
||||
`service:clipboard`,
|
||||
window.navigator.clipboard ? NavigatorClipboard : ExecClipboard
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
initialize,
|
||||
};
|
@ -6,7 +6,7 @@ const typeAssertion = (type, value, withDefault) => {
|
||||
return typeof value === type ? value : withDefault;
|
||||
};
|
||||
export default class WithCopyableModifier extends Modifier {
|
||||
@service('clipboard/os') clipboard;
|
||||
@service('clipboard') clipboard;
|
||||
|
||||
hash = null;
|
||||
source = null;
|
||||
@ -19,7 +19,9 @@ export default class WithCopyableModifier extends Modifier {
|
||||
return typeAssertion('function', _hash.success, () => {})(e);
|
||||
},
|
||||
error: e => {
|
||||
runInDebug(_ => console.info(`with-copyable: Error copying \`${value}\``));
|
||||
runInDebug(_ =>
|
||||
console.info(`with-copyable: Error copying \`${value}\` - ${e.toString()}`)
|
||||
);
|
||||
return typeAssertion('function', _hash.error, () => {})(e);
|
||||
},
|
||||
};
|
||||
|
65
ui/packages/consul-ui/app/services/clipboard/native.js
Normal file
65
ui/packages/consul-ui/app/services/clipboard/native.js
Normal file
@ -0,0 +1,65 @@
|
||||
import Service from '@ember/service';
|
||||
|
||||
const map = new WeakMap();
|
||||
// we should only have one listener per event per element as we have a thin
|
||||
// modifier layer over this.
|
||||
// Event arrays are guaranteed to exist as the arrays are created at the same
|
||||
// time as the functions themselves, if there are no arrays there are also no
|
||||
// functions to be called.
|
||||
const EVENTS = ['success', 'error'];
|
||||
const addEventListener = function(eventName, cb) {
|
||||
if (EVENTS.includes(eventName)) {
|
||||
map.get(this)[eventName].push(cb);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
const removeEventListener = function(eventName, cb) {
|
||||
if (EVENTS.includes(eventName)) {
|
||||
let listeners = map.get(this)[eventName];
|
||||
const pos = listeners.findIndex(item => item === cb);
|
||||
if (pos !== -1) {
|
||||
listeners.splice(pos, 1);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
//
|
||||
export default class OsService extends Service {
|
||||
constructor(owner, clipboard = window.navigator.clipboard) {
|
||||
super(...arguments);
|
||||
this.clipboard = clipboard;
|
||||
}
|
||||
execute($el, options) {
|
||||
// make a pseudo-target that follows the ClipboardJS emitter until we want
|
||||
// to reverse the interface
|
||||
const target = {
|
||||
on: addEventListener,
|
||||
off: removeEventListener,
|
||||
};
|
||||
// we only want to support clicking/pressing enter
|
||||
const click = e => {
|
||||
const text = options.text();
|
||||
// ClipboardJS events also have action and trigger props
|
||||
// but we don't use them
|
||||
this.clipboard.writeText(text).then(
|
||||
() => map.get(target).success.forEach(cb => cb({ text: text })),
|
||||
e => map.get(target).error.forEach(cb => cb(e))
|
||||
);
|
||||
};
|
||||
// add all the events as empty arrays
|
||||
map.set(
|
||||
target,
|
||||
EVENTS.reduce((prev, item) => {
|
||||
prev[item] = [];
|
||||
return prev;
|
||||
}, {})
|
||||
);
|
||||
// listen plus remove using ClipboardJS interface
|
||||
$el.addEventListener('click', click);
|
||||
target.destroy = function() {
|
||||
$el.removeEventListener('click', click);
|
||||
map.delete(target);
|
||||
};
|
||||
return target;
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
import Service from '@ember/service';
|
||||
|
||||
import Clipboard from 'clipboard';
|
||||
|
||||
export default class OsService extends Service {
|
||||
execute() {
|
||||
return new Clipboard(...arguments);
|
||||
}
|
||||
}
|
9
ui/packages/consul-ui/app/services/clipboard/polyfill.js
Normal file
9
ui/packages/consul-ui/app/services/clipboard/polyfill.js
Normal file
@ -0,0 +1,9 @@
|
||||
/* global ClipboardJS*/
|
||||
import Service from '@ember/service';
|
||||
|
||||
export default class PolyfillService extends Service {
|
||||
execute() {
|
||||
// Access the ClipboardJS lib see vendor/init.js for polyfill loading
|
||||
return new ClipboardJS(...arguments);
|
||||
}
|
||||
}
|
@ -136,6 +136,11 @@ module.exports = function(defaults, $ = process.env) {
|
||||
// CSS.escape polyfill
|
||||
app.import('node_modules/css.escape/css.escape.js', { outputFile: 'assets/css.escape.js' });
|
||||
|
||||
// Clipboard ponyfill
|
||||
app.import('node_modules/clipboard/dist/clipboard.js', {
|
||||
outputFile: 'assets/clipboard/clipboard.js',
|
||||
});
|
||||
|
||||
// JSON linting support. Possibly dynamically loaded via CodeMirror linting. See components/code-editor.js
|
||||
app.import('node_modules/jsonlint/lib/jsonlint.js', {
|
||||
outputFile: 'assets/codemirror/mode/javascript/javascript.js',
|
||||
|
@ -36,6 +36,7 @@ ${environment === 'production' ? `{{jsonEncode .}}` : JSON.stringify(config.oper
|
||||
"text-encoding/encoding-indexes.js": "${rootURL}assets/encoding-indexes.js",
|
||||
"text-encoding/encoding.js": "${rootURL}assets/encoding.js",
|
||||
"css.escape/css.escape.js": "${rootURL}assets/css.escape.js",
|
||||
"clipboard/clipboard.js": "${rootURL}assets/clipboard/clipboard.js",
|
||||
"codemirror/mode/javascript/javascript.js": "${rootURL}assets/codemirror/mode/javascript/javascript.js",
|
||||
"codemirror/mode/ruby/ruby.js": "${rootURL}assets/codemirror/mode/ruby/ruby.js",
|
||||
"codemirror/mode/yaml/yaml.js": "${rootURL}assets/codemirror/mode/yaml/yaml.js"
|
||||
|
3
ui/packages/consul-ui/vendor/init.js
vendored
3
ui/packages/consul-ui/vendor/init.js
vendored
@ -16,6 +16,9 @@
|
||||
if (!(window.CSS && window.CSS.escape)) {
|
||||
appendScript(fs.get(`${['css.escape', 'css.escape'].join('/')}.js`));
|
||||
}
|
||||
if (!window.navigator.clipboard) {
|
||||
appendScript(fs.get(`${['clipboard', 'clipboard'].join('/')}.js`));
|
||||
}
|
||||
|
||||
try {
|
||||
const $appMeta = doc.querySelector(`[name="${appName}/config/environment"]`);
|
||||
|
Loading…
x
Reference in New Issue
Block a user