Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1212)

Side by Side Diff: appengine/monorail/static/js/graveyard/popup_controller.js

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /* Copyright 2016 The Chromium Authors. All Rights Reserved.
2 *
3 * Use of this source code is governed by a BSD-style
4 * license that can be found in the LICENSE file or at
5 * https://developers.google.com/open-source/licenses/bsd
6 */
7
8 /**
9 * It is common to make a DIV temporarily visible to simulate
10 * a popup window. Often, this is done by adding an onClick
11 * handler to the element that can be clicked on to show the
12 * popup.
13 *
14 * Unfortunately, closing the popup is not as simple.
15 * The popup creator often wants to let the user close
16 * the popup by clicking elsewhere on the window; however,
17 * the popup only receives mouse events that occur
18 * on the popup itself. Thus, popups need a mechanism
19 * that notifies them that the user has clicked elsewhere
20 * to try to get rid of them.
21 *
22 * PopupController is such a mechanism --
23 * it monitors all mousedown events that
24 * occur in the window so that it can notify registered
25 * popups of the mousedown, and the popups can choose
26 * to deactivate themselves.
27 *
28 * For an object to qualify as a popup, it must have a
29 * function called "deactivate" that takes a mousedown event
30 * and returns a boolean indicating that it has deactivated
31 * itself as a result of that event.
32 *
33 * EXAMPLE:
34 *
35 * // popup that attaches itself to the supplied div
36 * function MyPopup(div) {
37 * this._div = div;
38 * this._isVisible = false;
39 * this._innerHTML = ...
40 * }
41 *
42 * MyPopup.prototype.show = function() {
43 * this._div.display = '';
44 * this._isVisible = true;
45 * PC_addPopup(this);
46 * }
47 *
48 * MyPopup.prototype.hide = function() {
49 * this._div.display = 'none';
50 * this._isVisible = false;
51 * }
52 *
53 * MyPopup.prototype.deactivate = function(e) {
54 * if (this._isVisible) {
55 * var p = GetMousePosition(e);
56 * if (nodeBounds(this._div).contains(p)) {
57 * return false; // use clicked on popup, remain visible
58 * } else {
59 * this.hide();
60 * return true; // clicked outside popup, make invisible
61 * }
62 * } else {
63 * return true; // already deactivated, not visible
64 * }
65 * }
66 *
67 * DEPENDENCIES (from this directory):
68 * bind.js
69 * listen.js
70 * common.js
71 * shapes.js
72 * geom.js
73 *
74 * USAGE:
75 * _PC_Install() must be called after the body is loaded
76 */
77
78 /**
79 * PopupController constructor.
80 * @constructor
81 */
82 function PopupController() {
83 this.activePopups_ = [];
84 }
85
86 /**
87 * @param {Document} opt_doc document to add PopupController to
88 * DEFAULT: "document" variable that is currently in scope
89 * @return {boolean} indicating if PopupController installed for the document;
90 * returns false if document already had PopupController
91 */
92 function _PC_Install(opt_doc) {
93 if (gPopupControllerInstalled) return false;
94 gPopupControllerInstalled = true;
95 var doc = (opt_doc) ? opt_doc : document;
96
97 // insert _notifyPopups in BODY's onmousedown chain
98 listen(doc.body, 'mousedown', PC_notifyPopups);
99 return true;
100 }
101
102 /**
103 * Notifies each popup of a mousedown event, giving
104 * each popup the chance to deactivate itself.
105 *
106 * @throws Error if a popup does not have a deactivate function
107 *
108 * @private
109 */
110 function PC_notifyPopups(e) {
111 if (gPopupController.activePopups_.length == 0) return false;
112 e = e || window.event;
113 for (var i = gPopupController.activePopups_.length - 1; i >= 0; --i) {
114 var popup = gPopupController.activePopups_[i];
115 PC_assertIsPopup(popup);
116 if (popup.deactivate(e)) {
117 gPopupController.activePopups_.splice(i, 1);
118 }
119 }
120 return true;
121 }
122
123 /**
124 * Adds the popup to the list of popups to be
125 * notified of a mousedown event.
126 *
127 * @return boolean indicating if added popup; false if already contained
128 * @throws Error if popup does not have a deactivate function
129 */
130 function PC_addPopup(popup) {
131 PC_assertIsPopup(popup);
132 for (var i = 0; i < gPopupController.activePopups_.length; ++i) {
133 if (popup === gPopupController.activePopups_[i]) return false;
134 }
135 gPopupController.activePopups_.push(popup);
136 return true;
137 }
138
139 /** asserts that popup has a deactivate function */
140 function PC_assertIsPopup(popup) {
141 AssertType(popup.deactivate, Function, 'popup missing deactivate function');
142 }
143
144 var gPopupController = new PopupController();
145 var gPopupControllerInstalled = false;
OLDNEW
« no previous file with comments | « appengine/monorail/static/js/graveyard/listen.js ('k') | appengine/monorail/static/js/graveyard/shapes.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698