OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Action links are elements that are used to perform an in-page navigation or | 5 // Action links are elements that are used to perform an in-page navigation or |
6 // action (e.g. showing a dialog). | 6 // action (e.g. showing a dialog). |
7 // | 7 // |
8 // They look like normal anchor (<a>) tags as their text color is blue. However, | 8 // They look like normal anchor (<a>) tags as their text color is blue. However, |
9 // they're subtly different as they're not initially underlined (giving users a | 9 // they're subtly different as they're not initially underlined (giving users a |
10 // clue that underlined links navigate while action links don't). | 10 // clue that underlined links navigate while action links don't). |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 if (!this.disabled && e.key == 'Enter' && !this.href) { | 47 if (!this.disabled && e.key == 'Enter' && !this.href) { |
48 // Schedule a click asynchronously because other 'keydown' handlers | 48 // Schedule a click asynchronously because other 'keydown' handlers |
49 // may still run later (e.g. document.addEventListener('keydown')). | 49 // may still run later (e.g. document.addEventListener('keydown')). |
50 // Specifically options dialogs break when this timeout isn't here. | 50 // Specifically options dialogs break when this timeout isn't here. |
51 // NOTE: this affects the "trusted" state of the ensuing click. I | 51 // NOTE: this affects the "trusted" state of the ensuing click. I |
52 // haven't found anything that breaks because of this (yet). | 52 // haven't found anything that breaks because of this (yet). |
53 window.setTimeout(this.click.bind(this), 0); | 53 window.setTimeout(this.click.bind(this), 0); |
54 } | 54 } |
55 }); | 55 }); |
56 | 56 |
57 function preventDefault(e) { | 57 function preventDefault(e) { e.preventDefault(); } |
58 e.preventDefault(); | |
59 } | |
60 | 58 |
61 function removePreventDefault() { | 59 function removePreventDefault() { |
62 document.removeEventListener('selectstart', preventDefault); | 60 document.removeEventListener('selectstart', preventDefault); |
63 document.removeEventListener('mouseup', removePreventDefault); | 61 document.removeEventListener('mouseup', removePreventDefault); |
64 } | 62 } |
65 | 63 |
66 this.addEventListener('mousedown', function() { | 64 this.addEventListener('mousedown', function() { |
67 // This handlers strives to match the behavior of <a href="...">. | 65 // This handlers strives to match the behavior of <a href="...">. |
68 | 66 |
69 // While the mouse is down, prevent text selection from dragging. | 67 // While the mouse is down, prevent text selection from dragging. |
70 document.addEventListener('selectstart', preventDefault); | 68 document.addEventListener('selectstart', preventDefault); |
71 document.addEventListener('mouseup', removePreventDefault); | 69 document.addEventListener('mouseup', removePreventDefault); |
72 | 70 |
73 // If focus started via mouse press, don't show an outline. | 71 // If focus started via mouse press, don't show an outline. |
74 if (document.activeElement != this) | 72 if (document.activeElement != this) |
75 this.classList.add('no-outline'); | 73 this.classList.add('no-outline'); |
76 }); | 74 }); |
77 | 75 |
78 this.addEventListener('blur', function() { | 76 this.addEventListener( |
79 this.classList.remove('no-outline'); | 77 'blur', function() { this.classList.remove('no-outline'); }); |
80 }); | |
81 }, | 78 }, |
82 | 79 |
83 /** @type {boolean} */ | 80 /** @type {boolean} */ |
84 set disabled(disabled) { | 81 set disabled(disabled) { |
85 if (disabled) | 82 if (disabled) |
86 HTMLAnchorElement.prototype.setAttribute.call(this, 'disabled', ''); | 83 HTMLAnchorElement.prototype.setAttribute.call(this, 'disabled', ''); |
87 else | 84 else |
88 HTMLAnchorElement.prototype.removeAttribute.call(this, 'disabled'); | 85 HTMLAnchorElement.prototype.removeAttribute.call(this, 'disabled'); |
89 this.tabIndex = disabled ? -1 : 0; | 86 this.tabIndex = disabled ? -1 : 0; |
90 }, | 87 }, |
91 get disabled() { | 88 get disabled() { return this.hasAttribute('disabled'); }, |
92 return this.hasAttribute('disabled'); | |
93 }, | |
94 | 89 |
95 /** @override */ | 90 /** @override */ |
96 setAttribute: function(attr, val) { | 91 setAttribute: function(attr, val) { |
97 if (attr.toLowerCase() == 'disabled') | 92 if (attr.toLowerCase() == 'disabled') |
98 this.disabled = true; | 93 this.disabled = true; |
99 else | 94 else |
100 HTMLAnchorElement.prototype.setAttribute.apply(this, arguments); | 95 HTMLAnchorElement.prototype.setAttribute.apply(this, arguments); |
101 }, | 96 }, |
102 | 97 |
103 /** @override */ | 98 /** @override */ |
104 removeAttribute: function(attr) { | 99 removeAttribute: function(attr) { |
105 if (attr.toLowerCase() == 'disabled') | 100 if (attr.toLowerCase() == 'disabled') |
106 this.disabled = false; | 101 this.disabled = false; |
107 else | 102 else |
108 HTMLAnchorElement.prototype.removeAttribute.apply(this, arguments); | 103 HTMLAnchorElement.prototype.removeAttribute.apply(this, arguments); |
109 }, | 104 }, |
110 }, | 105 }, |
111 | 106 |
112 extends: 'a', | 107 extends: 'a', |
113 }); | 108 }); |
OLD | NEW |