From 3b04ecd4abda15ba2288979f0ce2076a6ad5979d Mon Sep 17 00:00:00 2001 From: varun shivaprasad Date: Thu, 26 Apr 2018 14:09:04 +0530 Subject: [PATCH 01/11] feat: oui clipboard migrate cui clipboard to oui-clipboard design changes as per cx specs tooltip added on hover of the element tooltip bindin chaned to one way binding from one time binding cui clipboard to oui --- packages/oui-angular/src/index.js | 4 +- packages/oui-angular/src/index.spec.js | 1 + packages/oui-clipboard/README.md | 11 +++ .../oui-clipboard/src/clipboard.component.js | 13 +++ .../oui-clipboard/src/clipboard.controller.js | 50 ++++++++++ packages/oui-clipboard/src/clipboard.html | 11 +++ .../oui-clipboard/src/clipboard.provider.js | 42 +++++++++ packages/oui-clipboard/src/index.js | 6 ++ packages/oui-clipboard/src/index.spec.js | 91 +++++++++++++++++++ 9 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 packages/oui-clipboard/README.md create mode 100644 packages/oui-clipboard/src/clipboard.component.js create mode 100644 packages/oui-clipboard/src/clipboard.controller.js create mode 100644 packages/oui-clipboard/src/clipboard.html create mode 100644 packages/oui-clipboard/src/clipboard.provider.js create mode 100644 packages/oui-clipboard/src/index.js create mode 100644 packages/oui-clipboard/src/index.spec.js diff --git a/packages/oui-angular/src/index.js b/packages/oui-angular/src/index.js index 61ca5c65..cfbd0b70 100644 --- a/packages/oui-angular/src/index.js +++ b/packages/oui-angular/src/index.js @@ -28,6 +28,7 @@ import "@oui-angular/oui-chips/src"; import "@oui-angular/oui-popover/src"; import "@oui-angular/oui-stepper/src"; import "@oui-angular/oui-skeleton/src"; +import "@oui-angular/oui-clipboard/src"; angular.module("oui", [ "oui.button", @@ -59,5 +60,6 @@ angular.module("oui", [ "oui.chips", "oui.popover", "oui.stepper", - "oui.skeleton" + "oui.skeleton", + "oui.clipboard" ]); diff --git a/packages/oui-angular/src/index.spec.js b/packages/oui-angular/src/index.spec.js index e0a634ce..df59e3c1 100644 --- a/packages/oui-angular/src/index.spec.js +++ b/packages/oui-angular/src/index.spec.js @@ -29,6 +29,7 @@ loadTests(require.context("../../oui-chips/src/", true, /.*((\.spec)|(index))$/) loadTests(require.context("../../oui-popover/src/", true, /.*((\.spec)|(index))$/)); loadTests(require.context("../../oui-stepper/src/", true, /.*((\.spec)|(index))$/)); loadTests(require.context("../../oui-skeleton/src/", true, /.*((\.spec)|(index))$/)); +loadTests(require.context("../../oui-clipboard/src/", true, /.*((\.spec)|(index))$/)); function loadTests (context) { context.keys().forEach(context); diff --git a/packages/oui-clipboard/README.md b/packages/oui-clipboard/README.md new file mode 100644 index 00000000..e592387f --- /dev/null +++ b/packages/oui-clipboard/README.md @@ -0,0 +1,11 @@ +# Form Actions + + + +## Usage + +### Default + +```html:preview + +``` diff --git a/packages/oui-clipboard/src/clipboard.component.js b/packages/oui-clipboard/src/clipboard.component.js new file mode 100644 index 00000000..a98e2d69 --- /dev/null +++ b/packages/oui-clipboard/src/clipboard.component.js @@ -0,0 +1,13 @@ +import controller from "./clipboard.controller"; +import template from "./clipboard.html"; + +export default { + template, + controller, + controllerAs: "$clipctrl", + bindings: { + label: " this.reset(), switchBackDelay); + } + + handleResult (succeeded) { + if (succeeded) { + this.status = this.ouiClipboardConfiguration.status.success; + this.tooltipText = this.translations.copied_label; + } else { + this.reset(); + } + } + + reset () { + this.tooltipText = this.translations.copy_to_clipboard_label; + this.status = this.ouiClipboardConfiguration.status.initial; + } +} diff --git a/packages/oui-clipboard/src/clipboard.html b/packages/oui-clipboard/src/clipboard.html new file mode 100644 index 00000000..3b48d94e --- /dev/null +++ b/packages/oui-clipboard/src/clipboard.html @@ -0,0 +1,11 @@ +
+ + + +
diff --git a/packages/oui-clipboard/src/clipboard.provider.js b/packages/oui-clipboard/src/clipboard.provider.js new file mode 100644 index 00000000..7fc71ee9 --- /dev/null +++ b/packages/oui-clipboard/src/clipboard.provider.js @@ -0,0 +1,42 @@ +export default class { + constructor () { + this.translations = { + copy_to_clipboard_label: "Copy to Clipboard", + copied_label: "Copied" + }; + this.action = { + copy: "copy" + }; + this.status = { + initial: "initial", + success: "success" + }; + } + + /** + * Set the translations + * @param {Object} translations a map of translations + */ + setTranslations (translations) { + this.translations = translations; + return this; + } + + setStatus (status) { + this.status = status; + return this; + } + + setAction (copy) { + this.action = copy; + return this; + } + + $get () { + return { + action: this.action, + status: this.status, + translations: this.translations + }; + } +} diff --git a/packages/oui-clipboard/src/index.js b/packages/oui-clipboard/src/index.js new file mode 100644 index 00000000..7173ae55 --- /dev/null +++ b/packages/oui-clipboard/src/index.js @@ -0,0 +1,6 @@ +import Clipboard from "./clipboard.component.js"; +import ClipboardProvider from "./clipboard.provider.js"; + +angular + .module("oui.clipboard", []).component("ouiClipboard", Clipboard) + .provider("ouiClipboardConfiguration", ClipboardProvider); diff --git a/packages/oui-clipboard/src/index.spec.js b/packages/oui-clipboard/src/index.spec.js new file mode 100644 index 00000000..7e761101 --- /dev/null +++ b/packages/oui-clipboard/src/index.spec.js @@ -0,0 +1,91 @@ +describe("ouiClipboard", () => { + let TestUtils; + const copy_to_clipboard_label = "Copy to Clipboard"; + const copied_label = "Copied"; + const copy = "copy"; + const initial = "initial"; + const success = "success"; + + beforeEach(angular.mock.module("oui.clipboard")); + beforeEach(angular.mock.module("oui.test-utils")); + beforeEach(angular.mock.module("test.clipboardConfig")); + + angular.module("test.clipboardConfig", [ + "oui.clipboard" + ]).config(ouiClipboardConfigurationProvider => { + ouiClipboardConfigurationProvider.setTranslations({ + copy_to_clipboard_label, + copied_label + }); + ouiClipboardConfigurationProvider.setStatus({ + initial, + success + }); + ouiClipboardConfigurationProvider.setAction({ + copy + }); + }); + + beforeEach(inject(_TestUtils_ => { + TestUtils = _TestUtils_; + })); + + function getInputElement (element) { + return element[0].querySelector("input[type=text]"); + } + + describe("Provider", () => { + let configuration; + + beforeEach(inject(_ouiClipboardConfiguration_ => { + configuration = _ouiClipboardConfiguration_; + })); + + it("should have custom values", () => { + expect(configuration.translations.copy_to_clipboard_label).toEqual(copy_to_clipboard_label); + expect(configuration.translations.copied_label).toEqual(copied_label); + }); + }); + + describe("Component", () => { + + describe("text field", () => { + it("should generate an input for the componet which has the text given", () => { + const element = TestUtils.compileTemplate(""); + + expect(getInputElement(element)).toBeDefined(); + const inputElement = getInputElement(element); + expect(angular.element(inputElement).val()).toMatch("copy this text"); + }); + + it("controller status should be initial", () => { + + const element = TestUtils.compileTemplate(""); + const $ctrl = element.controller("ouiClipboard"); + expect($ctrl.status).toEqual(initial); + expect($ctrl.ouiClipboardConfiguration.action.copy).toEqual(copy); + }); + + it("on focus status should change to success", () => { + const element = TestUtils.compileTemplate(""); + + const inputElement = getInputElement(element); + const $inputElement = angular.element(inputElement); + + const $ctrl = element.controller("ouiClipboard"); + $inputElement.triggerHandler("focus"); + expect($ctrl.status).toEqual(success); + }); + + it("on reset tool tip text and status set to initial", () => { + const element = TestUtils.compileTemplate(""); + const $ctrl = element.controller("ouiClipboard"); + $ctrl.reset(); + $ctrl.handleResult(false); + expect($ctrl.tooltipText).toEqual(copy_to_clipboard_label); + expect($ctrl.status).toEqual(initial); + }); + + }); + }); +}); From 016f52b48871b1ab1986b2fa6a32a5f32d2d0188 Mon Sep 17 00:00:00 2001 From: varun shivaprasad Date: Thu, 26 Apr 2018 16:02:08 +0530 Subject: [PATCH 02/11] feat: oui clipboard add default parameters remove unnecessary code add width based html in readme cui clipboard to oui --- packages/oui-clipboard/README.md | 12 ++++++++++- .../oui-clipboard/src/clipboard.component.js | 2 -- .../oui-clipboard/src/clipboard.controller.js | 12 ++++++----- packages/oui-clipboard/src/clipboard.html | 21 ++++++++++--------- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/packages/oui-clipboard/README.md b/packages/oui-clipboard/README.md index e592387f..b0e5ebb6 100644 --- a/packages/oui-clipboard/README.md +++ b/packages/oui-clipboard/README.md @@ -7,5 +7,15 @@ ### Default ```html:preview - + + +``` + +### Clipboard contained in width of the parent + +```html:preview +
+ + +
``` diff --git a/packages/oui-clipboard/src/clipboard.component.js b/packages/oui-clipboard/src/clipboard.component.js index a98e2d69..9de75991 100644 --- a/packages/oui-clipboard/src/clipboard.component.js +++ b/packages/oui-clipboard/src/clipboard.component.js @@ -6,8 +6,6 @@ export default { controller, controllerAs: "$clipctrl", bindings: { - label: " - - - +
+
+ + + +
From 1200e693f78eb721ca211f1e7ef8328f7133d15b Mon Sep 17 00:00:00 2001 From: varun shivaprasad Date: Wed, 2 May 2018 14:45:54 +0530 Subject: [PATCH 03/11] feat: oui clipboard rewrite html for clipboard with input group rename tooltip and clipboard controller add api for tooltip and clipboard cui clipboard to oui --- packages/oui-clipboard/README.md | 14 +++++++++----- packages/oui-clipboard/src/clipboard.component.js | 2 +- .../oui-clipboard/src/clipboard.controller.js | 15 ++++++++------- packages/oui-clipboard/src/clipboard.html | 15 ++++++--------- packages/oui-clipboard/src/clipboard.provider.js | 4 ++-- packages/oui-clipboard/src/index.spec.js | 14 +++++++------- packages/oui-tooltip/README.md | 2 +- packages/oui-tooltip/src/tooltip.html | 2 +- 8 files changed, 35 insertions(+), 33 deletions(-) diff --git a/packages/oui-clipboard/README.md b/packages/oui-clipboard/README.md index b0e5ebb6..af7983e8 100644 --- a/packages/oui-clipboard/README.md +++ b/packages/oui-clipboard/README.md @@ -7,15 +7,19 @@ ### Default ```html:preview - - + ``` ### Clipboard contained in width of the parent ```html:preview -
- - +
+
``` + +## API + +| Attribute | Type | Binding | One-time Binding | Values | Default | Description | +| ---- | ---- | ---- | ---- | ---- | ---- | ---- | +| text | string | @? | true | | | clipboard text | diff --git a/packages/oui-clipboard/src/clipboard.component.js b/packages/oui-clipboard/src/clipboard.component.js index 9de75991..e8ca6b59 100644 --- a/packages/oui-clipboard/src/clipboard.component.js +++ b/packages/oui-clipboard/src/clipboard.component.js @@ -4,7 +4,7 @@ import template from "./clipboard.html"; export default { template, controller, - controllerAs: "$clipctrl", + controllerAs: "$ctrl", bindings: { text: "@?" } diff --git a/packages/oui-clipboard/src/clipboard.controller.js b/packages/oui-clipboard/src/clipboard.controller.js index 1cc58e15..e697e9cc 100644 --- a/packages/oui-clipboard/src/clipboard.controller.js +++ b/packages/oui-clipboard/src/clipboard.controller.js @@ -1,4 +1,5 @@ import { addDefaultParameter } from "@oui-angular/common/component-utils"; + const switchBackDelay = 2000; export default class { constructor ($attrs, $scope, $element, $timeout, ouiClipboardConfiguration) { @@ -10,14 +11,14 @@ export default class { this.ouiClipboardConfiguration = ouiClipboardConfiguration; } - $postLink () { + $onInit () { addDefaultParameter(this, "translations", this.ouiClipboardConfiguration.translations); addDefaultParameter(this, "status", this.ouiClipboardConfiguration.status.initial); - addDefaultParameter(this, "tooltipText", this.ouiClipboardConfiguration.translations.copy_to_clipboard_label); + addDefaultParameter(this, "tooltipText", this.ouiClipboardConfiguration.translations.copyToClipboardLabel); } - onTextFocus ($event) { - $event.target.select(); + onClick () { + this.$element.find("input")[0].select(); this.copyText(); } @@ -27,9 +28,9 @@ export default class { try { document.execCommand(this.ouiClipboardConfiguration.action.copy); } catch (err) { - console.log(err); this.error = err; succeeded = false; + throw new Error("Could not copy text to clipboard."); } this.handleResult(succeeded); @@ -39,14 +40,14 @@ export default class { handleResult (succeeded) { if (succeeded) { this.status = this.ouiClipboardConfiguration.status.success; - this.tooltipText = this.translations.copied_label; + this.tooltipText = this.translations.copiedLabel; } else { this.reset(); } } reset () { - this.tooltipText = this.translations.copy_to_clipboard_label; + this.tooltipText = this.translations.copyToClipboardLabel; this.status = this.ouiClipboardConfiguration.status.initial; } } diff --git a/packages/oui-clipboard/src/clipboard.html b/packages/oui-clipboard/src/clipboard.html index a020ef49..ceec4e5e 100644 --- a/packages/oui-clipboard/src/clipboard.html +++ b/packages/oui-clipboard/src/clipboard.html @@ -1,12 +1,9 @@ -
-
- +
+ - - +
-
+
\ No newline at end of file diff --git a/packages/oui-clipboard/src/clipboard.provider.js b/packages/oui-clipboard/src/clipboard.provider.js index 7fc71ee9..794ea9fc 100644 --- a/packages/oui-clipboard/src/clipboard.provider.js +++ b/packages/oui-clipboard/src/clipboard.provider.js @@ -1,8 +1,8 @@ export default class { constructor () { this.translations = { - copy_to_clipboard_label: "Copy to Clipboard", - copied_label: "Copied" + copyToClipboardLabel: "Copy to Clipboard", + copiedLabel: "Copied" }; this.action = { copy: "copy" diff --git a/packages/oui-clipboard/src/index.spec.js b/packages/oui-clipboard/src/index.spec.js index 7e761101..9e29506e 100644 --- a/packages/oui-clipboard/src/index.spec.js +++ b/packages/oui-clipboard/src/index.spec.js @@ -1,7 +1,7 @@ describe("ouiClipboard", () => { let TestUtils; - const copy_to_clipboard_label = "Copy to Clipboard"; - const copied_label = "Copied"; + const copyToClipboardLabel = "Copy to Clipboard"; + const copiedLabel = "Copied"; const copy = "copy"; const initial = "initial"; const success = "success"; @@ -14,8 +14,8 @@ describe("ouiClipboard", () => { "oui.clipboard" ]).config(ouiClipboardConfigurationProvider => { ouiClipboardConfigurationProvider.setTranslations({ - copy_to_clipboard_label, - copied_label + copyToClipboardLabel, + copiedLabel }); ouiClipboardConfigurationProvider.setStatus({ initial, @@ -42,8 +42,8 @@ describe("ouiClipboard", () => { })); it("should have custom values", () => { - expect(configuration.translations.copy_to_clipboard_label).toEqual(copy_to_clipboard_label); - expect(configuration.translations.copied_label).toEqual(copied_label); + expect(configuration.translations.copyToClipboardLabel).toEqual(copyToClipboardLabel); + expect(configuration.translations.copiedLabel).toEqual(copiedLabel); }); }); @@ -82,7 +82,7 @@ describe("ouiClipboard", () => { const $ctrl = element.controller("ouiClipboard"); $ctrl.reset(); $ctrl.handleResult(false); - expect($ctrl.tooltipText).toEqual(copy_to_clipboard_label); + expect($ctrl.tooltipText).toEqual(copyToClipboardLabel); expect($ctrl.status).toEqual(initial); }); diff --git a/packages/oui-tooltip/README.md b/packages/oui-tooltip/README.md index bfa0a2d8..264ae69b 100644 --- a/packages/oui-tooltip/README.md +++ b/packages/oui-tooltip/README.md @@ -46,7 +46,7 @@ If there is no `aria-label` attribute, the directive create one based on `oui-to | Attribute | Type | Binding | One-time Binding | Values | Default | Description | | ---- | ---- | ---- | ---- | ---- | ---- | ---- | -| oui-tooltip | string | @ | true | | | tooltip text | +| oui-tooltip | string | @ | | | | tooltip text | | oui-tooltip-placement | string | @? | true | top,top-start,top-end,bottom,bottom-start,bottom-end | top | tooltip placement | diff --git a/packages/oui-tooltip/src/tooltip.html b/packages/oui-tooltip/src/tooltip.html index 996838b3..ce3eb6c7 100644 --- a/packages/oui-tooltip/src/tooltip.html +++ b/packages/oui-tooltip/src/tooltip.html @@ -1 +1 @@ - + From 88ee812fbfa3ec9a0caef5b5d4e3b142183d7f4e Mon Sep 17 00:00:00 2001 From: Jean-Frederic Durand Date: Thu, 17 May 2018 15:33:08 -0400 Subject: [PATCH 04/11] feat(oui-clipboard): add attributes id, name fix tests add test for id and name attributes --- packages/oui-clipboard/README.md | 20 +++++++---- .../oui-clipboard/src/clipboard.component.js | 4 ++- .../oui-clipboard/src/clipboard.controller.js | 10 ++++++ packages/oui-clipboard/src/clipboard.html | 9 +++-- packages/oui-clipboard/src/index.spec.js | 36 +++++++++++++------ 5 files changed, 58 insertions(+), 21 deletions(-) diff --git a/packages/oui-clipboard/README.md b/packages/oui-clipboard/README.md index af7983e8..d385c46e 100644 --- a/packages/oui-clipboard/README.md +++ b/packages/oui-clipboard/README.md @@ -1,6 +1,6 @@ -# Form Actions +# Clipboard - + ## Usage @@ -13,13 +13,21 @@ ### Clipboard contained in width of the parent ```html:preview -
+
``` +### Clipboard with name and id attribute + +```html:preview + +``` + ## API -| Attribute | Type | Binding | One-time Binding | Values | Default | Description | -| ---- | ---- | ---- | ---- | ---- | ---- | ---- | -| text | string | @? | true | | | clipboard text | +| Attribute | Type | Binding | One-time Binding | Values | Default | Description | +| ---- | ---- | ---- | ---- | ---- | ---- | ---- | +| text | string | @? | true | | | clipboard text | +| id | string | @? | true | | | id attribute of the input | +| name | string | @? | true | | | name attribute of the input | diff --git a/packages/oui-clipboard/src/clipboard.component.js b/packages/oui-clipboard/src/clipboard.component.js index e8ca6b59..8e7807d9 100644 --- a/packages/oui-clipboard/src/clipboard.component.js +++ b/packages/oui-clipboard/src/clipboard.component.js @@ -6,6 +6,8 @@ export default { controller, controllerAs: "$ctrl", bindings: { - text: "@?" + text: "@?", + name: "@?", + id: "@?" } }; diff --git a/packages/oui-clipboard/src/clipboard.controller.js b/packages/oui-clipboard/src/clipboard.controller.js index e697e9cc..a89fb417 100644 --- a/packages/oui-clipboard/src/clipboard.controller.js +++ b/packages/oui-clipboard/src/clipboard.controller.js @@ -17,6 +17,16 @@ export default class { addDefaultParameter(this, "tooltipText", this.ouiClipboardConfiguration.translations.copyToClipboardLabel); } + $postLink () { + // Sometimes the digest cycle is done before dom manipulation, + // So we use $timeout to force the $apply + this.$timeout(() => + this.$element + .removeAttr("id") + .removeAttr("name") + ); + } + onClick () { this.$element.find("input")[0].select(); this.copyText(); diff --git a/packages/oui-clipboard/src/clipboard.html b/packages/oui-clipboard/src/clipboard.html index ceec4e5e..e671eadc 100644 --- a/packages/oui-clipboard/src/clipboard.html +++ b/packages/oui-clipboard/src/clipboard.html @@ -1,9 +1,12 @@
-
+
-
\ No newline at end of file +
diff --git a/packages/oui-clipboard/src/index.spec.js b/packages/oui-clipboard/src/index.spec.js index 9e29506e..f48f8e18 100644 --- a/packages/oui-clipboard/src/index.spec.js +++ b/packages/oui-clipboard/src/index.spec.js @@ -34,6 +34,10 @@ describe("ouiClipboard", () => { return element[0].querySelector("input[type=text]"); } + function getContainerElement (element) { + return element[0].querySelector(".oui-input-group_clipboard_container"); + } + describe("Provider", () => { let configuration; @@ -50,35 +54,45 @@ describe("ouiClipboard", () => { describe("Component", () => { describe("text field", () => { - it("should generate an input for the componet which has the text given", () => { - const element = TestUtils.compileTemplate(""); + it("should generate an input with the given text", () => { + const element = TestUtils.compileTemplate(""); expect(getInputElement(element)).toBeDefined(); const inputElement = getInputElement(element); expect(angular.element(inputElement).val()).toMatch("copy this text"); }); - it("controller status should be initial", () => { + it("should generate an input with name and id attribute", () => { + const element = TestUtils.compileTemplate(""); - const element = TestUtils.compileTemplate(""); + expect(getInputElement(element)).toBeDefined(); + const inputElement = getInputElement(element); + expect(angular.element(inputElement).attr("id")).toBe("id"); + expect(angular.element(inputElement).attr("name")).toBe("name"); + }); + + it("should let status to initial", () => { + + const element = TestUtils.compileTemplate(""); const $ctrl = element.controller("ouiClipboard"); expect($ctrl.status).toEqual(initial); expect($ctrl.ouiClipboardConfiguration.action.copy).toEqual(copy); }); - it("on focus status should change to success", () => { - const element = TestUtils.compileTemplate(""); + it("should change status to success on click", () => { + const element = TestUtils.compileTemplate(""); - const inputElement = getInputElement(element); - const $inputElement = angular.element(inputElement); + const containerElement = getContainerElement(element); + const $containerElement = angular.element(containerElement); const $ctrl = element.controller("ouiClipboard"); - $inputElement.triggerHandler("focus"); + $containerElement.triggerHandler("click"); + expect($ctrl.status).toEqual(success); }); - it("on reset tool tip text and status set to initial", () => { - const element = TestUtils.compileTemplate(""); + it("should reset tool tip text and set status to initial", () => { + const element = TestUtils.compileTemplate(""); const $ctrl = element.controller("ouiClipboard"); $ctrl.reset(); $ctrl.handleResult(false); From 70f43979a0e3e7dc838dfe3a1e684cec83f3b838 Mon Sep 17 00:00:00 2001 From: Jean-Frederic Durand Date: Wed, 23 May 2018 15:18:56 -0400 Subject: [PATCH 05/11] refactor(oui-clipboard): replicate BEM changes --- packages/oui-clipboard/src/clipboard.html | 2 +- packages/oui-clipboard/src/index.spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/oui-clipboard/src/clipboard.html b/packages/oui-clipboard/src/clipboard.html index e671eadc..1ba0c91b 100644 --- a/packages/oui-clipboard/src/clipboard.html +++ b/packages/oui-clipboard/src/clipboard.html @@ -1,5 +1,5 @@
-
+
{ } function getContainerElement (element) { - return element[0].querySelector(".oui-input-group_clipboard_container"); + return element[0].querySelector(".oui-input-group_clipboard-container"); } describe("Provider", () => { From a70750eed4aedff94cc38ba4c4748835da676d0d Mon Sep 17 00:00:00 2001 From: Axel Peter Date: Wed, 30 May 2018 14:54:56 +0200 Subject: [PATCH 06/11] chore(oui-clipboard): code review --- packages/oui-clipboard/README.md | 57 +++--- .../oui-clipboard/src/clipboard.component.js | 26 +-- .../oui-clipboard/src/clipboard.controller.js | 111 +++++------ packages/oui-clipboard/src/clipboard.html | 22 +-- .../oui-clipboard/src/clipboard.provider.js | 66 +++---- packages/oui-clipboard/src/index.spec.js | 184 ++++++++---------- packages/oui-stepper/src/stepper.provider.js | 4 + 7 files changed, 202 insertions(+), 268 deletions(-) diff --git a/packages/oui-clipboard/README.md b/packages/oui-clipboard/README.md index d385c46e..5f95752e 100644 --- a/packages/oui-clipboard/README.md +++ b/packages/oui-clipboard/README.md @@ -1,33 +1,24 @@ -# Clipboard - - - -## Usage - -### Default - -```html:preview - -``` - -### Clipboard contained in width of the parent - -```html:preview -
- -
-``` - -### Clipboard with name and id attribute - -```html:preview - -``` - -## API - -| Attribute | Type | Binding | One-time Binding | Values | Default | Description | -| ---- | ---- | ---- | ---- | ---- | ---- | ---- | -| text | string | @? | true | | | clipboard text | -| id | string | @? | true | | | id attribute of the input | -| name | string | @? | true | | | name attribute of the input | +# Clipboard + + + +## Usage + +### Default + +```html:preview +
+ +
+
+

Model value: {{$ctrl.clipboardModel | json}}

+
+``` + +## API + +| Attribute | Type | Binding | One-time Binding | Values | Default | Description +| ---- | ---- | ---- | ---- | ---- | ---- | ---- +| id | string | @? | true | | | id attribute of the input +| name | string | @? | true | | | name attribute of the input +| model | string | @? | true | | | clipboard model diff --git a/packages/oui-clipboard/src/clipboard.component.js b/packages/oui-clipboard/src/clipboard.component.js index 8e7807d9..6528c952 100644 --- a/packages/oui-clipboard/src/clipboard.component.js +++ b/packages/oui-clipboard/src/clipboard.component.js @@ -1,13 +1,13 @@ -import controller from "./clipboard.controller"; -import template from "./clipboard.html"; - -export default { - template, - controller, - controllerAs: "$ctrl", - bindings: { - text: "@?", - name: "@?", - id: "@?" - } -}; +import controller from "./clipboard.controller"; +import template from "./clipboard.html"; + +export default { + template, + controller, + controllerAs: "$ctrl", + bindings: { + name: "@?", + id: "@?", + model: " - this.$element - .removeAttr("id") - .removeAttr("name") - ); - } - - onClick () { - this.$element.find("input")[0].select(); - this.copyText(); - } - - copyText () { - let succeeded = true; - - try { - document.execCommand(this.ouiClipboardConfiguration.action.copy); - } catch (err) { - this.error = err; - succeeded = false; - throw new Error("Could not copy text to clipboard."); - } - - this.handleResult(succeeded); - this.$timeout(() => this.reset(), switchBackDelay); - } - - handleResult (succeeded) { - if (succeeded) { - this.status = this.ouiClipboardConfiguration.status.success; - this.tooltipText = this.translations.copiedLabel; - } else { - this.reset(); - } - } - - reset () { - this.tooltipText = this.translations.copyToClipboardLabel; - this.status = this.ouiClipboardConfiguration.status.initial; - } -} +const switchBackDelay = 2000; +export default class { + constructor ($attrs, $element, $timeout, ouiClipboardConfiguration) { + "ngInject"; + this.$attrs = $attrs; + this.$element = $element; + this.$timeout = $timeout; + this.translations = angular.copy(ouiClipboardConfiguration.translations); + } + + $onInit () { + this.tooltipText = this.translations.copyToClipboardLabel; + } + + $postLink () { + // Sometimes the digest cycle is done before dom manipulation, + // So we use $timeout to force the $apply + this.$timeout(() => + this.$element + .addClass("oui-input-group") + .addClass("oui-input-group_clipboard") + .removeAttr("id") + .removeAttr("name") + ); + } + + onClick () { + this.$timeout(() => { + this.$element.find("input")[0].select(); + this.copyText(); + }); + } + + copyText () { + try { + document.execCommand("copy"); + this.tooltipText = this.translations.copiedLabel; + this.$timeout(() => this.reset(), switchBackDelay); + } catch (err) { + this.error = err; + throw new Error("Could not copy text to clipboard."); + } + } + + reset () { + this.tooltipText = this.translations.copyToClipboardLabel; + } +} diff --git a/packages/oui-clipboard/src/clipboard.html b/packages/oui-clipboard/src/clipboard.html index 1ba0c91b..e9ea46ba 100644 --- a/packages/oui-clipboard/src/clipboard.html +++ b/packages/oui-clipboard/src/clipboard.html @@ -1,12 +1,10 @@ -
-
- - -
-
+
+ + +
diff --git a/packages/oui-clipboard/src/clipboard.provider.js b/packages/oui-clipboard/src/clipboard.provider.js index 794ea9fc..a11f0b36 100644 --- a/packages/oui-clipboard/src/clipboard.provider.js +++ b/packages/oui-clipboard/src/clipboard.provider.js @@ -1,42 +1,24 @@ -export default class { - constructor () { - this.translations = { - copyToClipboardLabel: "Copy to Clipboard", - copiedLabel: "Copied" - }; - this.action = { - copy: "copy" - }; - this.status = { - initial: "initial", - success: "success" - }; - } - - /** - * Set the translations - * @param {Object} translations a map of translations - */ - setTranslations (translations) { - this.translations = translations; - return this; - } - - setStatus (status) { - this.status = status; - return this; - } - - setAction (copy) { - this.action = copy; - return this; - } - - $get () { - return { - action: this.action, - status: this.status, - translations: this.translations - }; - } -} +import { merge } from "lodash"; +export default class { + constructor () { + this.translations = { + copyToClipboardLabel: "Copy to Clipboard", + copiedLabel: "Copied" + }; + } + + /** + * Set the translations + * @param {Object} translations a map of translations + */ + setTranslations (translations) { + this.translations = merge(this.translations, translations); + return this; + } + + $get () { + return { + translations: this.translations + }; + } +} diff --git a/packages/oui-clipboard/src/index.spec.js b/packages/oui-clipboard/src/index.spec.js index 446bacb7..df9100a5 100644 --- a/packages/oui-clipboard/src/index.spec.js +++ b/packages/oui-clipboard/src/index.spec.js @@ -1,105 +1,79 @@ -describe("ouiClipboard", () => { - let TestUtils; - const copyToClipboardLabel = "Copy to Clipboard"; - const copiedLabel = "Copied"; - const copy = "copy"; - const initial = "initial"; - const success = "success"; - - beforeEach(angular.mock.module("oui.clipboard")); - beforeEach(angular.mock.module("oui.test-utils")); - beforeEach(angular.mock.module("test.clipboardConfig")); - - angular.module("test.clipboardConfig", [ - "oui.clipboard" - ]).config(ouiClipboardConfigurationProvider => { - ouiClipboardConfigurationProvider.setTranslations({ - copyToClipboardLabel, - copiedLabel - }); - ouiClipboardConfigurationProvider.setStatus({ - initial, - success - }); - ouiClipboardConfigurationProvider.setAction({ - copy - }); - }); - - beforeEach(inject(_TestUtils_ => { - TestUtils = _TestUtils_; - })); - - function getInputElement (element) { - return element[0].querySelector("input[type=text]"); - } - - function getContainerElement (element) { - return element[0].querySelector(".oui-input-group_clipboard-container"); - } - - describe("Provider", () => { - let configuration; - - beforeEach(inject(_ouiClipboardConfiguration_ => { - configuration = _ouiClipboardConfiguration_; - })); - - it("should have custom values", () => { - expect(configuration.translations.copyToClipboardLabel).toEqual(copyToClipboardLabel); - expect(configuration.translations.copiedLabel).toEqual(copiedLabel); - }); - }); - - describe("Component", () => { - - describe("text field", () => { - it("should generate an input with the given text", () => { - const element = TestUtils.compileTemplate(""); - - expect(getInputElement(element)).toBeDefined(); - const inputElement = getInputElement(element); - expect(angular.element(inputElement).val()).toMatch("copy this text"); - }); - - it("should generate an input with name and id attribute", () => { - const element = TestUtils.compileTemplate(""); - - expect(getInputElement(element)).toBeDefined(); - const inputElement = getInputElement(element); - expect(angular.element(inputElement).attr("id")).toBe("id"); - expect(angular.element(inputElement).attr("name")).toBe("name"); - }); - - it("should let status to initial", () => { - - const element = TestUtils.compileTemplate(""); - const $ctrl = element.controller("ouiClipboard"); - expect($ctrl.status).toEqual(initial); - expect($ctrl.ouiClipboardConfiguration.action.copy).toEqual(copy); - }); - - it("should change status to success on click", () => { - const element = TestUtils.compileTemplate(""); - - const containerElement = getContainerElement(element); - const $containerElement = angular.element(containerElement); - - const $ctrl = element.controller("ouiClipboard"); - $containerElement.triggerHandler("click"); - - expect($ctrl.status).toEqual(success); - }); - - it("should reset tool tip text and set status to initial", () => { - const element = TestUtils.compileTemplate(""); - const $ctrl = element.controller("ouiClipboard"); - $ctrl.reset(); - $ctrl.handleResult(false); - expect($ctrl.tooltipText).toEqual(copyToClipboardLabel); - expect($ctrl.status).toEqual(initial); - }); - - }); - }); -}); +describe("ouiClipboard", () => { + let $timeout; + let testUtils; + let configuration; + + beforeEach(angular.mock.module("oui.clipboard")); + beforeEach(angular.mock.module("oui.clipboard.configuration")); + beforeEach(angular.mock.module("oui.test-utils")); + + beforeEach(inject((_$timeout_, _TestUtils_) => { + $timeout = _$timeout_; + testUtils = _TestUtils_; + })); + + describe("Provider", () => { + + angular.module("oui.clipboard.configuration", [ + "oui.clipboard" + ]).config(ouiClipboardConfigurationProvider => { + ouiClipboardConfigurationProvider.setTranslations({ + foo: "bar" + }); + }); + + beforeEach(inject(_ouiClipboardConfiguration_ => { + configuration = _ouiClipboardConfiguration_; + })); + + it("should have custom options", () => { + expect(configuration.translations.foo).toEqual("bar"); + }); + }); + + describe("Component", () => { + + describe("text field", () => { + it("should generate an input with the given text", () => { + const model = "foo"; + const element = testUtils.compileTemplate("", { + model + }); + + const inputElement = element[0].querySelector("input[type=text]"); + expect(angular.element(inputElement).val()).toMatch(model); + }); + + it("should generate an input with name and id attribute", () => { + const element = testUtils.compileTemplate(""); + const inputElement = element[0].querySelector("input[type=text]"); + + $timeout.flush(); + + expect(angular.element(inputElement).attr("id")).toBe("id"); + expect(angular.element(inputElement).attr("name")).toBe("name"); + }); + + it("should update tooltip text when copied on click", () => { + const element = testUtils.compileTemplate(""); + const inputElement = angular.element(element[0].querySelector("input[type=text]")); + const $ctrl = element.controller("ouiClipboard"); + + inputElement.triggerHandler("click"); + + $timeout.flush(); + expect($ctrl.tooltipText).toEqual(configuration.translations.copiedLabel); + }); + + it("should reset tooltip text", () => { + const element = testUtils.compileTemplate(""); + const $ctrl = element.controller("ouiClipboard"); + + $ctrl.reset(); + $timeout.flush(); + + expect($ctrl.tooltipText).toEqual(configuration.translations.copyToClipboardLabel); + }); + }); + }); +}); diff --git a/packages/oui-stepper/src/stepper.provider.js b/packages/oui-stepper/src/stepper.provider.js index 8d376281..74be80e6 100644 --- a/packages/oui-stepper/src/stepper.provider.js +++ b/packages/oui-stepper/src/stepper.provider.js @@ -12,6 +12,10 @@ export default class { }; } + /** + * Set the translations + * @param {Object} translations a map of translations + */ setTranslations (translations) { this.translations = merge(this.translations, translations); return this; From 4d54bc2a2314b7f5980265ef1fc3da8af9fe014e Mon Sep 17 00:00:00 2001 From: Axel Peter Date: Wed, 30 May 2018 15:30:05 +0200 Subject: [PATCH 07/11] chore: code review --- packages/oui-clipboard/src/clipboard.html | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/oui-clipboard/src/clipboard.html b/packages/oui-clipboard/src/clipboard.html index e9ea46ba..6c148fd0 100644 --- a/packages/oui-clipboard/src/clipboard.html +++ b/packages/oui-clipboard/src/clipboard.html @@ -1,10 +1,13 @@ -
+
- +
From d9918ffcda45879d7b065aeda8c6d3ad3f29617c Mon Sep 17 00:00:00 2001 From: Axel Peter Date: Thu, 31 May 2018 17:41:44 +0200 Subject: [PATCH 08/11] feat(oui-clipboard): use of clipboardjs library --- package.json | 5 +- .../oui-clipboard/src/clipboard.controller.js | 52 ++++++++++++------- packages/oui-clipboard/src/clipboard.html | 12 ++--- yarn.lock | 26 ++++++++++ 4 files changed, 68 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index 28ea5aff..3d597fba 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,10 @@ } }, "dependencies": { + "clipboard": "2.0.1", "escape-string-regexp": "^1.0.5", - "popper.js": "^1.12.9", - "flatpickr": "4.5.0" + "flatpickr": "4.5.0", + "popper.js": "^1.12.9" }, "devDependencies": { "angular": "~1.6.1", diff --git a/packages/oui-clipboard/src/clipboard.controller.js b/packages/oui-clipboard/src/clipboard.controller.js index 1906b5a3..4972fce5 100644 --- a/packages/oui-clipboard/src/clipboard.controller.js +++ b/packages/oui-clipboard/src/clipboard.controller.js @@ -1,3 +1,5 @@ +import Clipboard from "clipboard"; + const switchBackDelay = 2000; export default class { constructor ($attrs, $element, $timeout, ouiClipboardConfiguration) { @@ -10,36 +12,48 @@ export default class { $onInit () { this.tooltipText = this.translations.copyToClipboardLabel; + this.trigger = this.$element[0].querySelector(".oui-clipboard__button"); + this.target = this.$element[0].querySelector(".oui-clipboard__control"); + } + + $onDestroy () { + this.clipboard.destroy(); } $postLink () { - // Sometimes the digest cycle is done before dom manipulation, - // So we use $timeout to force the $apply - this.$timeout(() => + this.$timeout(() => { this.$element .addClass("oui-input-group") .addClass("oui-input-group_clipboard") .removeAttr("id") - .removeAttr("name") - ); - } + .removeAttr("name"); + }); - onClick () { - this.$timeout(() => { - this.$element.find("input")[0].select(); - this.copyText(); + // Init the clipboard instance + this.clipboard = new Clipboard(this.trigger, { + action: "copy", + target: () => this.target, + text: () => this.model }); + + // Events for updating the tooltip + this.clipboard + .on("success", () => { + this.$timeout(() => { + this.target.select(); + this.tooltipText = this.translations.copiedLabel; + }); + + // Reset after a delay + this.$timeout(() => this.reset(), switchBackDelay); + }) + .on("error", () => { + throw new Error("Could not copy text to clipboard."); + }); } - copyText () { - try { - document.execCommand("copy"); - this.tooltipText = this.translations.copiedLabel; - this.$timeout(() => this.reset(), switchBackDelay); - } catch (err) { - this.error = err; - throw new Error("Could not copy text to clipboard."); - } + onInputClick () { + this.trigger.click(); } reset () { diff --git a/packages/oui-clipboard/src/clipboard.html b/packages/oui-clipboard/src/clipboard.html index 6c148fd0..f44583fb 100644 --- a/packages/oui-clipboard/src/clipboard.html +++ b/packages/oui-clipboard/src/clipboard.html @@ -1,13 +1,13 @@ -
- + -
diff --git a/yarn.lock b/yarn.lock index fcf52c9d..dfceec7a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1851,6 +1851,14 @@ cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" +clipboard@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.1.tgz#a12481e1c13d8a50f5f036b0560fe5d16d74e46a" + dependencies: + good-listener "^1.2.2" + select "^1.1.2" + tiny-emitter "^2.0.0" + cliui@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" @@ -2595,6 +2603,10 @@ delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" +delegate@^3.1.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" + delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" @@ -3767,6 +3779,12 @@ globby@^5.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +good-listener@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50" + dependencies: + delegate "^3.1.2" + graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -7146,6 +7164,10 @@ schema-utils@^0.4.0, schema-utils@^0.4.5: ajv "^6.1.0" ajv-keywords "^3.1.0" +select@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" + "semver@2 || 3 || 4 || 5", semver@5.5.0, semver@^5.3.0, semver@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" @@ -7830,6 +7852,10 @@ timespan@2.3.x: version "2.3.0" resolved "https://registry.yarnpkg.com/timespan/-/timespan-2.3.0.tgz#4902ce040bd13d845c8f59b27e9d59bad6f39929" +tiny-emitter@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.0.2.tgz#82d27468aca5ade8e5fd1e6d22b57dd43ebdfb7c" + tmp@0.0.33, tmp@0.0.x, tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" From 729bd82ac9581569d3d57cc6f69225e58f7a4953 Mon Sep 17 00:00:00 2001 From: Axel Peter Date: Fri, 1 Jun 2018 15:26:07 +0200 Subject: [PATCH 09/11] feat(oui-clipboard): add fallback if no support --- .../oui-clipboard/src/clipboard.controller.js | 35 ++++---- packages/oui-clipboard/src/clipboard.html | 3 +- .../oui-clipboard/src/clipboard.provider.js | 3 +- packages/oui-clipboard/src/index.spec.js | 87 ++++++++++++------- 4 files changed, 81 insertions(+), 47 deletions(-) diff --git a/packages/oui-clipboard/src/clipboard.controller.js b/packages/oui-clipboard/src/clipboard.controller.js index 4972fce5..dc1f94d8 100644 --- a/packages/oui-clipboard/src/clipboard.controller.js +++ b/packages/oui-clipboard/src/clipboard.controller.js @@ -1,6 +1,4 @@ import Clipboard from "clipboard"; - -const switchBackDelay = 2000; export default class { constructor ($attrs, $element, $timeout, ouiClipboardConfiguration) { "ngInject"; @@ -31,25 +29,25 @@ export default class { // Init the clipboard instance this.clipboard = new Clipboard(this.trigger, { - action: "copy", target: () => this.target, text: () => this.model }); // Events for updating the tooltip this.clipboard - .on("success", () => { - this.$timeout(() => { - this.target.select(); - this.tooltipText = this.translations.copiedLabel; - }); - - // Reset after a delay - this.$timeout(() => this.reset(), switchBackDelay); - }) - .on("error", () => { - throw new Error("Could not copy text to clipboard."); - }); + .on("success", () => this.selectInputText(this.translations.copiedLabel)) + .on("error", () => this.selectInputText(this.translations.notSupported)); + } + + selectInputText (tooltipText) { + const rangeSelection = 9999; + + this.$timeout(() => { + // Need to focus before selecting + this.target.focus(); + this.target.setSelectionRange(0, rangeSelection); + this.tooltipText = tooltipText; + }); } onInputClick () { @@ -57,6 +55,11 @@ export default class { } reset () { - this.tooltipText = this.translations.copyToClipboardLabel; + const resetDelay = 500; + + // Add delay for resetting after tooltip animation + this.$timeout(() => { + this.tooltipText = this.translations.copyToClipboardLabel; + }, resetDelay); } } diff --git a/packages/oui-clipboard/src/clipboard.html b/packages/oui-clipboard/src/clipboard.html index f44583fb..7924ca31 100644 --- a/packages/oui-clipboard/src/clipboard.html +++ b/packages/oui-clipboard/src/clipboard.html @@ -1,5 +1,6 @@
+ oui-tooltip="{{$ctrl.tooltipText}}" + ng-mouseleave="$ctrl.reset()"> { }); describe("Component", () => { + it("should generate an input with the given text", () => { + const model = "foo"; + const element = testUtils.compileTemplate("", { + model + }); - describe("text field", () => { - it("should generate an input with the given text", () => { - const model = "foo"; - const element = testUtils.compileTemplate("", { - model - }); + const inputElement = element[0].querySelector("input[type=text]"); + expect(angular.element(inputElement).val()).toMatch(model); + }); - const inputElement = element[0].querySelector("input[type=text]"); - expect(angular.element(inputElement).val()).toMatch(model); - }); + it("should generate an input with name and id attribute", () => { + const element = testUtils.compileTemplate(""); + const inputElement = element[0].querySelector("input[type=text]"); - it("should generate an input with name and id attribute", () => { - const element = testUtils.compileTemplate(""); - const inputElement = element[0].querySelector("input[type=text]"); + $timeout.flush(); - $timeout.flush(); + expect(angular.element(inputElement).attr("id")).toBe("id"); + expect(angular.element(inputElement).attr("name")).toBe("name"); + }); - expect(angular.element(inputElement).attr("id")).toBe("id"); - expect(angular.element(inputElement).attr("name")).toBe("name"); + it("should have an instance of clipboardjs", () => { + const model = "foo"; + const element = testUtils.compileTemplate("", { + model }); + const $ctrl = element.controller("ouiClipboard"); - it("should update tooltip text when copied on click", () => { - const element = testUtils.compileTemplate(""); - const inputElement = angular.element(element[0].querySelector("input[type=text]")); - const $ctrl = element.controller("ouiClipboard"); + expect($ctrl.clipboard).toBeDefined(); - inputElement.triggerHandler("click"); + const target = angular.element($ctrl.clipboard.target()); + expect(target.hasClass("oui-clipboard__control")).toBeTruthy(); + expect($ctrl.clipboard.text()).toBe(model); + }); - $timeout.flush(); - expect($ctrl.tooltipText).toEqual(configuration.translations.copiedLabel); + it("should update tooltip text when copied on click", (done) => { + const model = "bar"; + const element = testUtils.compileTemplate("", { + model }); + const btnElement = element[0].querySelector(".oui-clipboard__button"); + const $ctrl = element.controller("ouiClipboard"); + + $ctrl.clipboard + .on("success", () => { + $timeout.flush(); + expect($ctrl.tooltipText).toEqual(configuration.translations.copiedLabel); + done(); + }) + .on("error", () => { + $timeout.flush(); + expect($ctrl.tooltipText).toEqual(configuration.translations.notSupported); + done(); + }); - it("should reset tooltip text", () => { - const element = testUtils.compileTemplate(""); - const $ctrl = element.controller("ouiClipboard"); + btnElement.click(); + }); - $ctrl.reset(); - $timeout.flush(); + it("should reset tooltip text", () => { + const element = testUtils.compileTemplate(""); + const btnElement = element[0].querySelector(".oui-clipboard__button"); + const $ctrl = element.controller("ouiClipboard"); - expect($ctrl.tooltipText).toEqual(configuration.translations.copyToClipboardLabel); - }); + // Simulate click + btnElement.click(); + $timeout.flush(); + + // Then reset + $ctrl.reset(); + $timeout.flush(); + + expect($ctrl.tooltipText).toEqual(configuration.translations.copyToClipboardLabel); }); }); }); From bcb083a262dbe91fee7e8430b7f198365d593758 Mon Sep 17 00:00:00 2001 From: Axel Peter Date: Fri, 1 Jun 2018 17:05:50 +0200 Subject: [PATCH 10/11] chore(oui-clipboard): update tooltip text --- packages/oui-clipboard/src/clipboard.controller.js | 11 +++++++++-- packages/oui-clipboard/src/clipboard.provider.js | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/oui-clipboard/src/clipboard.controller.js b/packages/oui-clipboard/src/clipboard.controller.js index dc1f94d8..00ddee97 100644 --- a/packages/oui-clipboard/src/clipboard.controller.js +++ b/packages/oui-clipboard/src/clipboard.controller.js @@ -40,12 +40,19 @@ export default class { } selectInputText (tooltipText) { - const rangeSelection = 9999; + const selectionEnd = this.model.length; this.$timeout(() => { // Need to focus before selecting this.target.focus(); - this.target.setSelectionRange(0, rangeSelection); + + // Select text on the target + this.target.selectionStart = 0; + this.target.selectionEnd = selectionEnd; + this.target.setSelectionRange(0, selectionEnd); + this.target.select(); + + // Update tooltip text this.tooltipText = tooltipText; }); } diff --git a/packages/oui-clipboard/src/clipboard.provider.js b/packages/oui-clipboard/src/clipboard.provider.js index 00ab5c96..2477d4ac 100644 --- a/packages/oui-clipboard/src/clipboard.provider.js +++ b/packages/oui-clipboard/src/clipboard.provider.js @@ -4,7 +4,7 @@ export default class { this.translations = { copyToClipboardLabel: "Copy to Clipboard", copiedLabel: "Copied", - notSupported: "Not supported. Please copy the text manually" + notSupported: "Copy to Clipboard not supported. Please copy the text manually" }; } From eabf9d78f4ee64347ca99372a7184449f8da5397 Mon Sep 17 00:00:00 2001 From: Axel Peter Date: Mon, 4 Jun 2018 13:37:07 +0200 Subject: [PATCH 11/11] chore: code review --- packages/oui-clipboard/README.md | 20 ++++++++++++---- .../oui-clipboard/src/clipboard.component.js | 3 +-- .../oui-clipboard/src/clipboard.controller.js | 10 +++++--- packages/oui-clipboard/src/clipboard.html | 24 +++++++++---------- .../oui-clipboard/src/clipboard.provider.js | 4 ++-- packages/oui-clipboard/src/index.spec.js | 4 +++- 6 files changed, 40 insertions(+), 25 deletions(-) diff --git a/packages/oui-clipboard/README.md b/packages/oui-clipboard/README.md index 5f95752e..aa04d74f 100644 --- a/packages/oui-clipboard/README.md +++ b/packages/oui-clipboard/README.md @@ -7,11 +7,23 @@ ### Default ```html:preview -
- +
+
-

Model value: {{$ctrl.clipboardModel | json}}

+

Model value: {{$ctrl.simpleModel | json}}

+
+``` + +### Formatted text + +```html:preview +
+ +
+
+

Model value: {{$ctrl.formattedModel}}

``` @@ -21,4 +33,4 @@ | ---- | ---- | ---- | ---- | ---- | ---- | ---- | id | string | @? | true | | | id attribute of the input | name | string | @? | true | | | name attribute of the input -| model | string | @? | true | | | clipboard model +| model | object | = | true | | | model bound to component diff --git a/packages/oui-clipboard/src/clipboard.component.js b/packages/oui-clipboard/src/clipboard.component.js index 6528c952..d4b479f0 100644 --- a/packages/oui-clipboard/src/clipboard.component.js +++ b/packages/oui-clipboard/src/clipboard.component.js @@ -4,10 +4,9 @@ import template from "./clipboard.html"; export default { template, controller, - controllerAs: "$ctrl", bindings: { name: "@?", id: "@?", - model: " { this.$element - .addClass("oui-input-group") - .addClass("oui-input-group_clipboard") + .addClass("oui-input-group oui-input-group_clipboard") .removeAttr("id") .removeAttr("name"); }); @@ -40,7 +39,7 @@ export default class { } selectInputText (tooltipText) { - const selectionEnd = this.model.length; + const selectionEnd = this.model.length || 0; this.$timeout(() => { // Need to focus before selecting @@ -54,6 +53,11 @@ export default class { // Update tooltip text this.tooltipText = tooltipText; + + // Need to bind the reset like this because + // ClipboardJS triggered the "blur" event + // By copying in a fake textarea + angular.element(this.target).one("blur", () => this.reset()); }); } diff --git a/packages/oui-clipboard/src/clipboard.html b/packages/oui-clipboard/src/clipboard.html index 7924ca31..3171c5c9 100644 --- a/packages/oui-clipboard/src/clipboard.html +++ b/packages/oui-clipboard/src/clipboard.html @@ -1,14 +1,12 @@ -
- - -
+ readonly> + diff --git a/packages/oui-clipboard/src/clipboard.provider.js b/packages/oui-clipboard/src/clipboard.provider.js index 2477d4ac..5564aa7a 100644 --- a/packages/oui-clipboard/src/clipboard.provider.js +++ b/packages/oui-clipboard/src/clipboard.provider.js @@ -2,9 +2,9 @@ import { merge } from "lodash"; export default class { constructor () { this.translations = { - copyToClipboardLabel: "Copy to Clipboard", + copyToClipboardLabel: "Copy to clipboard", copiedLabel: "Copied", - notSupported: "Copy to Clipboard not supported. Please copy the text manually" + notSupported: "Copy to clipboard not supported. Please copy the text manually" }; } diff --git a/packages/oui-clipboard/src/index.spec.js b/packages/oui-clipboard/src/index.spec.js index 2a471c20..8b80a439 100644 --- a/packages/oui-clipboard/src/index.spec.js +++ b/packages/oui-clipboard/src/index.spec.js @@ -90,7 +90,9 @@ describe("ouiClipboard", () => { }); it("should reset tooltip text", () => { - const element = testUtils.compileTemplate(""); + const element = testUtils.compileTemplate("", { + model: "foo" + }); const btnElement = element[0].querySelector(".oui-clipboard__button"); const $ctrl = element.controller("ouiClipboard");