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

Unified Diff: appengine/monorail/static/js/graveyard/common.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 side-by-side diff with in-line comments
Download patch
Index: appengine/monorail/static/js/graveyard/common.js
diff --git a/appengine/monorail/static/js/graveyard/common.js b/appengine/monorail/static/js/graveyard/common.js
new file mode 100644
index 0000000000000000000000000000000000000000..ebc9306a67fee8c9e3864b331940608546094d8c
--- /dev/null
+++ b/appengine/monorail/static/js/graveyard/common.js
@@ -0,0 +1,719 @@
+/* Copyright 2016 The Chromium Authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://developers.google.com/open-source/licenses/bsd
+ */
+
+//------------------------------------------------------------------------
+// This file contains common utilities and basic javascript infrastructure.
+//
+// Notes:
+// * Press 'D' to toggle debug mode.
+//
+// Functions:
+//
+// - Assertions
+// DEPRECATED: Use assert.js
+// AssertTrue(): assert an expression. Throws an exception if false.
+// Fail(): Throws an exception. (Mark block of code that should be unreachable)
+// AssertEquals(): assert that two values are equal.
+// AssertType(): assert that a value has a particular type
+//
+// - Cookies
+// SetCookie(): Sets a cookie.
+// ExpireCookie(): Expires a cookie.
+// GetCookie(): Gets a cookie value.
+//
+// - Dynamic HTML/DOM utilities
+// MaybeGetElement(): get an element by its id
+// GetElement(): get an element by its id
+// GetParentNode(): Get the parent of an element
+// GetAttribute(): Get attribute value of a DOM node
+// GetInnerHTML(): get the inner HTML of a node
+// SetCssStyle(): Sets a CSS property of a node.
+// GetStyleProperty(): Get CSS property from a style attribute string
+// GetCellIndex(): Get the index of a table cell in a table row
+// ShowElement(): Show/hide element by setting the "display" css property.
+// ShowBlockElement(): Show/hide block element
+// SetButtonText(): Set the text of a button element.
+// AppendNewElement(): Create and append a html element to a parent node.
+// CreateDIV(): Create a DIV element and append to the document.
+// HasClass(): check if element has a given class
+// AddClass(): add a class to an element
+// RemoveClass(): remove a class from an element
+//
+// - Window/Screen utiltiies
+// GetPageOffsetLeft(): get the X page offset of an element
+// GetPageOffsetTop(): get the Y page offset of an element
+// GetPageOffset(): get the X and Y page offsets of an element
+// GetPageOffsetRight() : get X page offset of the right side of an element
+// GetPageOffsetRight() : get Y page offset of the bottom of an element
+// GetScrollTop(): get the vertical scrolling pos of a window.
+// GetScrollLeft(): get the horizontal scrolling pos of a window
+// IsScrollAtEnd(): check if window scrollbar has reached its maximum offset
+// ScrollTo(): scroll window to a position
+// ScrollIntoView(): scroll window so that an element is in view.
+// GetWindowWidth(): get width of a window.
+// GetWindowHeight(): get height of a window
+// GetAvailScreenWidth(): get available screen width
+// GetAvailScreenHeight(): get available screen height
+// GetNiceWindowHeight(): get a nice height for a new browser window.
+// Open{External/Internal}Window(): open a separate window
+// CloseWindow(): close a window
+//
+// - DOM walking utilities
+// AnnotateTerms(): find terms in a node and decorate them with some tag
+// AnnotateText(): find terms in a text node and decorate them with some tag
+//
+// - String utilties
+// HtmlEscape(): html escapes a string
+// HtmlUnescape(): remove html-escaping.
+// QuoteEscape(): escape " quotes.
+// CollapseWhitespace(): collapse multiple whitespace into one whitespace.
+// Trim(): trim whitespace on ends of string
+// IsEmpty(): check if CollapseWhiteSpace(String) == ""
+// IsLetterOrDigit(): check if a character is a letter or a digit
+// ConvertEOLToLF(): normalize the new-lines of a string.
+// HtmlEscapeInsertWbrs(): HtmlEscapes and inserts <wbr>s (word break tags)
+// after every n non-space chars and/or after or before certain special chars
+//
+// - TextArea utilities
+// GetCursorPos(): finds the cursor position of a textfield
+// SetCursorPos(): sets the cursor position in a textfield
+//
+// - Array utilities
+// FindInArray(): do a linear search to find an element value.
+// DeleteArrayElement(): return a new array with a specific value removed.
+// CloneObject(): clone an object, copying its values recursively.
+// CloneEvent(): clone an event; cannot use CloneObject because it
+// suffers from infinite recursion
+//
+// - Formatting utilities
+// PrintArray(): used to print/generate HTML by combining static text
+// and dynamic strings.
+// ImageHtml(): create html for an img tag
+// FormatJSLink(): formats a link that invokes js code when clicked.
+// MakeId3(): formats an id that has two id numbers, eg, foo_3_7
+//
+// - Timeouts
+// SafeTimeout(): sets a timeout with protection against ugly JS-errors
+// CancelTimeout(): cancels a timeout with a given ID
+// CancelAllTimeouts(): cancels all timeouts on a given window
+//
+// - Miscellaneous
+// IsDefined(): returns true if argument is not undefined
+//------------------------------------------------------------------------
+
+// browser detection
+function BR_AgentContains_(str) {
+ if (str in BR_AgentContains_cache_) {
+ return BR_AgentContains_cache_[str];
+ }
+
+ return BR_AgentContains_cache_[str] =
+ (navigator.userAgent.toLowerCase().indexOf(str) != -1);
+}
+// We cache the results of the indexOf operation. This gets us a 10x benefit in
+// Gecko, 8x in Safari and 4x in MSIE for all of the browser checks
+var BR_AgentContains_cache_ = {};
+
+function BR_IsIE() {
+ return (BR_AgentContains_('msie') || BR_AgentContains_('trident')) &&
+ !window.opera;
+}
+
+function BR_IsKonqueror() {
+ return BR_AgentContains_('konqueror');
+}
+
+function BR_IsSafari() {
+ return BR_AgentContains_('safari') || BR_IsKonqueror();
+}
+
+function BR_IsNav() {
+ return !BR_IsIE() &&
+ !BR_IsSafari() &&
+ BR_AgentContains_('mozilla');
+}
+
+var BACKSPACE_KEYCODE = 8;
+var COMMA_KEYCODE = 188; // ',' key
+var DEBUG_KEYCODE = 68; // 'D' key
+var DELETE_KEYCODE = 46;
+var DOWN_KEYCODE = 40; // DOWN arrow key
+var ENTER_KEYCODE = 13; // ENTER key
+var ESC_KEYCODE = 27; // ESC key
+var LEFT_KEYCODE = 37; // LEFT arrow key
+var RIGHT_KEYCODE = 39; // RIGHT arrow key
+var SPACE_KEYCODE = 32; // space bar
+var TAB_KEYCODE = 9; // TAB key
+var UP_KEYCODE = 38; // UP arrow key
+var SHIFT_KEYCODE = 16;
+var PAGE_DOWN_KEYCODE = 34;
+var PAGE_UP_KEYCODE = 33;
+
+var MAX_EMAIL_ADDRESS_LENGTH = 320; // 64 + '@' + 255
+var MAX_SIGNATURE_LENGTH = 1000; // 1000 chars of maximum signature
+
+//------------------------------------------------------------------------
+// Assertions
+// DEPRECATED: Use assert.js
+//------------------------------------------------------------------------
+/**
+ * DEPRECATED: Use assert.js
+ */
+function raise(msg) {
+ if (typeof Error != 'undefined') {
+ throw new Error(msg || 'Assertion Failed');
+ } else {
+ throw (msg);
+ }
+}
+
+/**
+ * DEPRECATED: Use assert.js
+ *
+ * Fail() is useful for marking logic paths that should
+ * not be reached. For example, if you have a class that uses
+ * ints for enums:
+ *
+ * MyClass.ENUM_FOO = 1;
+ * MyClass.ENUM_BAR = 2;
+ * MyClass.ENUM_BAZ = 3;
+ *
+ * And a switch statement elsewhere in your code that
+ * has cases for each of these enums, then you can
+ * "protect" your code as follows:
+ *
+ * switch(type) {
+ * case MyClass.ENUM_FOO: doFooThing(); break;
+ * case MyClass.ENUM_BAR: doBarThing(); break;
+ * case MyClass.ENUM_BAZ: doBazThing(); break;
+ * default:
+ * Fail("No enum in MyClass with value: " + type);
+ * }
+ *
+ * This way, if someone introduces a new value for this enum
+ * without noticing this switch statement, then the code will
+ * fail if the logic allows it to reach the switch with the
+ * new value, alerting the developer that he should add a
+ * case to the switch to handle the new value he has introduced.
+ *
+ * @param {string} opt_msg to display for failure
+ * DEFAULT: "Assertion failed"
+ */
+function Fail(opt_msg) {
+ opt_msg = opt_msg || 'Assertion failed';
+ if (IsDefined(DumpError)) DumpError(opt_msg + '\n');
+ raise(opt_msg);
+}
+
+/**
+ * DEPRECATED: Use assert.js
+ *
+ * Asserts that an expression is true (non-zero and non-null).
+ *
+ * Note that it is critical not to pass logic
+ * with side-effects as the expression for AssertTrue
+ * because if the assertions are removed by the
+ * JSCompiler, then the expression will be removed
+ * as well, in which case the side-effects will
+ * be lost. So instead of this:
+ *
+ * AssertTrue( criticalComputation() );
+ *
+ * Do this:
+ *
+ * var result = criticalComputation();
+ * AssertTrue(result);
+ *
+ * @param expression to evaluate
+ * @param {string} opt_msg to display if the assertion fails
+ *
+ */
+function AssertTrue(expression, opt_msg) {
+ if (!expression) {
+ opt_msg = opt_msg || 'Assertion failed';
+ Fail(opt_msg);
+ }
+}
+
+/**
+ * DEPRECATED: Use assert.js
+ *
+ * Asserts that a value is of the provided type.
+ *
+ * AssertType(6, Number);
+ * AssertType("ijk", String);
+ * AssertType([], Array);
+ * AssertType({}, Object);
+ * AssertType(ICAL_Date.now(), ICAL_Date);
+ *
+ * @param value
+ * @param type A constructor function
+ * @param {string} opt_msg to display if the assertion fails
+ */
+function AssertType(value, type, opt_msg) {
+ // for backwards compatability only
+ if (typeof value == type) return;
+
+ if (value || value == "") {
+ try {
+ if (type == AssertTypeMap[typeof value] || value instanceof type) return;
+ } catch (e) { /* failure, type was an illegal argument to instanceof */ }
+ }
+ var makeMsg = opt_msg === undefined;
+ if (makeMsg) {
+ if (typeof type == 'function') {
+ var match = type.toString().match(/^\s*function\s+([^\s\{]+)/);
+ if (match) type = match[1];
+ }
+ opt_msg = "AssertType failed: <" + value + "> not typeof "+ type;
+ }
+ Fail(opt_msg);
+}
+
+var AssertTypeMap = {
+ 'string' : String,
+ 'number' : Number,
+ 'boolean' : Boolean
+};
+
+var EXPIRED_COOKIE_VALUE = 'EXPIRED';
+
+
+//------------------------------------------------------------------------
+// Window/screen utilities
+// TODO: these should be renamed (e.g. GetWindowWidth to GetWindowInnerWidth
+// and moved to geom.js)
+//------------------------------------------------------------------------
+// Get page offset of an element
+function GetPageOffsetLeft(el) {
+ var x = el.offsetLeft;
+ if (el.offsetParent != null)
+ x += GetPageOffsetLeft(el.offsetParent);
+ return x;
+}
+
+// Get page offset of an element
+function GetPageOffsetTop(el) {
+ var y = el.offsetTop;
+ if (el.offsetParent != null)
+ y += GetPageOffsetTop(el.offsetParent);
+ return y;
+}
+
+// Get page offset of an element
+function GetPageOffset(el) {
+ var x = el.offsetLeft;
+ var y = el.offsetTop;
+ if (el.offsetParent != null) {
+ var pos = GetPageOffset(el.offsetParent);
+ x += pos.x;
+ y += pos.y;
+ }
+ return {x: x, y: y};
+}
+
+// Get the y position scroll offset.
+function GetScrollTop(win) {
+ return GetWindowPropertyByBrowser_(win, getScrollTopGetters_);
+}
+
+var getScrollTopGetters_ = {
+ ieQuirks_: function(win) {
+ return win.document.body.scrollTop;
+ },
+ ieStandards_: function(win) {
+ return win.document.documentElement.scrollTop;
+ },
+ dom_: function(win) {
+ return win.pageYOffset;
+ }
+};
+
+// Get the x position scroll offset.
+function GetScrollLeft(win) {
+ return GetWindowPropertyByBrowser_(win, getScrollLeftGetters_);
+}
+
+var getScrollLeftGetters_ = {
+ ieQuirks_: function(win) {
+ return win.document.body.scrollLeft;
+ },
+ ieStandards_: function(win) {
+ return win.document.documentElement.scrollLeft;
+ },
+ dom_: function(win) {
+ return win.pageXOffset;
+ }
+};
+
+// Scroll so that as far as possible the entire element is in view.
+var ALIGN_BOTTOM = 'b';
+var ALIGN_MIDDLE = 'm';
+var ALIGN_TOP = 't';
+
+var getWindowWidthGetters_ = {
+ ieQuirks_: function(win) {
+ return win.document.body.clientWidth;
+ },
+ ieStandards_: function(win) {
+ return win.document.documentElement.clientWidth;
+ },
+ dom_: function(win) {
+ return win.innerWidth;
+ }
+};
+
+function GetWindowHeight(win) {
+ return GetWindowPropertyByBrowser_(win, getWindowHeightGetters_);
+}
+
+var getWindowHeightGetters_ = {
+ ieQuirks_: function(win) {
+ return win.document.body.clientHeight;
+ },
+ ieStandards_: function(win) {
+ return win.document.documentElement.clientHeight;
+ },
+ dom_: function(win) {
+ return win.innerHeight;
+ }
+};
+
+/**
+ * Allows the easy use of different getters for IE quirks mode, IE standards
+ * mode and fully DOM-compliant browers.
+ *
+ * @param win window to get the property for
+ * @param getters object with various getters. Invoked with the passed window.
+ * There are three properties:
+ * - ieStandards_: IE 6.0 standards mode
+ * - ieQuirks_: IE 6.0 quirks mode and IE 5.5 and older
+ * - dom_: Mozilla, Safari and other fully DOM compliant browsers
+ *
+ * @private
+ */
+function GetWindowPropertyByBrowser_(win, getters) {
+ try {
+ if (BR_IsSafari()) {
+ return getters.dom_(win);
+ } else if (!window.opera &&
+ "compatMode" in win.document &&
+ win.document.compatMode == "CSS1Compat") {
+ return getters.ieStandards_(win);
+ } else if (BR_IsIE()) {
+ return getters.ieQuirks_(win);
+ }
+ } catch (e) {
+ // Ignore for now and fall back to DOM method
+ }
+
+ return getters.dom_(win);
+}
+
+function GetAvailScreenWidth(win) {
+ return win.screen.availWidth;
+}
+
+// Used for horizontally centering a new window of the given width in the
+// available screen. Set the new window's distance from the left of the screen
+// equal to this function's return value.
+// Params: width: the width of the new window
+// Returns: the distance from the left edge of the screen for the new window to
+// be horizontally centered
+function GetCenteringLeft(win, width) {
+ return (win.screen.availWidth - width) >> 1;
+}
+
+// Used for vertically centering a new window of the given height in the
+// available screen. Set the new window's distance from the top of the screen
+// equal to this function's return value.
+// Params: height: the height of the new window
+// Returns: the distance from the top edge of the screen for the new window to
+// be vertically aligned.
+function GetCenteringTop(win, height) {
+ return (win.screen.availHeight - height) >> 1;
+}
+
+/**
+ * Opens a child popup window that has no browser toolbar/decorations.
+ * (Copied from caribou's common.js library with small modifications.)
+ *
+ * @param url the URL for the new window (Note: this will be unique-ified)
+ * @param opt_name the name of the new window
+ * @param opt_width the width of the new window
+ * @param opt_height the height of the new window
+ * @param opt_center if true, the new window is centered in the available screen
+ * @param opt_hide_scrollbars if true, the window hides the scrollbars
+ * @param opt_noresize if true, makes window unresizable
+ * @param opt_blocked_msg message warning that the popup has been blocked
+ * @return {Window} a reference to the new child window
+ */
+function Popup(url, opt_name, opt_width, opt_height, opt_center,
+ opt_hide_scrollbars, opt_noresize, opt_blocked_msg) {
+ if (!opt_height) {
+ opt_height = Math.floor(GetWindowHeight(window.top) * 0.8);
+ }
+ if (!opt_width) {
+ opt_width = Math.min(GetAvailScreenWidth(window), opt_height);
+ }
+
+ var features = "resizable=" + (opt_noresize ? "no" : "yes") + "," +
+ "scrollbars=" + (opt_hide_scrollbars ? "no" : "yes") + "," +
+ "width=" + opt_width + ",height=" + opt_height;
+ if (opt_center) {
+ features += ",left=" + GetCenteringLeft(window, opt_width) + "," +
+ "top=" + GetCenteringTop(window, opt_height);
+ }
+ return OpenWindow(window, url, opt_name, features, opt_blocked_msg);
+}
+
+/**
+ * Opens a new window. Returns the new window handle. Tries to open the new
+ * window using top.open() first. If that doesn't work, then tries win.open().
+ * If that still doesn't work, prints an alert.
+ * (Copied from caribou's common.js library with small modifications.)
+ *
+ * @param win the parent window from which to open the new child window
+ * @param url the URL for the new window (Note: this will be unique-ified)
+ * @param opt_name the name of the new window
+ * @param opt_features the properties of the new window
+ * @param opt_blocked_msg message warning that the popup has been blocked
+ * @return {Window} a reference to the new child window
+ */
+function OpenWindow(win, url, opt_name, opt_features, opt_blocked_msg) {
+ var newwin = OpenWindowHelper(top, url, opt_name, opt_features);
+ if (!newwin || newwin.closed || !newwin.focus) {
+ newwin = OpenWindowHelper(win, url, opt_name, opt_features);
+ }
+ if (!newwin || newwin.closed || !newwin.focus) {
+ if (opt_blocked_msg) alert(opt_blocked_msg);
+ } else {
+ // Make sure that the window has the focus
+ newwin.focus();
+ }
+ return newwin;
+}
+
+/*
+ * Helper for OpenWindow().
+ * (Copied from caribou's common.js library with small modifications.)
+ */
+function OpenWindowHelper(win, url, name, features) {
+ var newwin;
+ if (features) {
+ newwin = win.open(url, name, features);
+ } else if (name) {
+ newwin = win.open(url, name);
+ } else {
+ newwin = win.open(url);
+ }
+ return newwin;
+}
+
+//------------------------------------------------------------------------
+// String utilities
+//------------------------------------------------------------------------
+// Do html escaping
+var amp_re_ = /&/g;
+var lt_re_ = /</g;
+var gt_re_ = />/g;
+
+// converts multiple ws chars to a single space, and strips
+// leading and trailing ws
+var spc_re_ = /\s+/g;
+var beg_spc_re_ = /^ /;
+var end_spc_re_ = / $/;
+
+var newline_re_ = /\r?\n/g;
+var spctab_re_ = /[ \t]+/g;
+var nbsp_re_ = /\xa0/g;
+
+// URL-decodes the string. We need to specially handle '+'s because
+// the javascript library doesn't properly convert them to spaces
+var plus_re_ = /\+/g;
+
+// Converts any instances of "\r" or "\r\n" style EOLs into "\n" (Line Feed),
+// and also trim the extra newlines and whitespaces at the end.
+var eol_re_ = /\r\n?/g;
+var trailingspc_re_ = /[\n\t ]+$/;
+
+// Converts a string to its canonicalized label form.
+var illegal_chars_re_ = /[ \/(){}&|\\\"\000]/g;
+
+//------------------------------------------------------------------------
+// TextArea utilities
+//------------------------------------------------------------------------
+
+// Gets the cursor pos in a text area. Returns -1 if the cursor pos cannot
+// be determined or if the cursor out of the textfield.
+function GetCursorPos(win, textfield) {
+ try {
+ if (IsDefined(textfield.selectionEnd)) {
+ // Mozilla directly supports this
+ return textfield.selectionEnd;
+
+ } else if (win.document.selection && win.document.selection.createRange) {
+ // IE doesn't export an accessor for the endpoints of a selection.
+ // Instead, it uses the TextRange object, which has an extremely obtuse
+ // API. Here's what seems to work:
+
+ // (1) Obtain a textfield from the current selection (cursor)
+ var tr = win.document.selection.createRange();
+
+ // Check if the current selection is in the textfield
+ if (tr.parentElement() != textfield) {
+ return -1;
+ }
+
+ // (2) Make a text range encompassing the textfield
+ var tr2 = tr.duplicate();
+ tr2.moveToElementText(textfield);
+
+ // (3) Move the end of the copy to the beginning of the selection
+ tr2.setEndPoint("EndToStart", tr);
+
+ // (4) The span of the textrange copy is equivalent to the cursor pos
+ var cursor = tr2.text.length;
+
+ // Finally, perform a sanity check to make sure the cursor is in the
+ // textfield. IE sometimes screws this up when the window is activated
+ if (cursor > textfield.value.length) {
+ return -1;
+ }
+ return cursor;
+ } else {
+ Debug("Unable to get cursor position for: " + navigator.userAgent);
+
+ // Just return the size of the textfield
+ // TODO: Investigate how to get cursor pos in Safari!
+ return textfield.value.length;
+ }
+ } catch (e) {
+ DumpException(e, "Cannot get cursor pos");
+ }
+
+ return -1;
+}
+
+function SetCursorPos(win, textfield, pos) {
+ if (IsDefined(textfield.selectionEnd) &&
+ IsDefined(textfield.selectionStart)) {
+ // Mozilla directly supports this
+ textfield.selectionStart = pos;
+ textfield.selectionEnd = pos;
+
+ } else if (win.document.selection && textfield.createTextRange) {
+ // IE has textranges. A textfield's textrange encompasses the
+ // entire textfield's text by default
+ var sel = textfield.createTextRange();
+
+ sel.collapse(true);
+ sel.move("character", pos);
+ sel.select();
+ }
+}
+
+//------------------------------------------------------------------------
+// Array utilities
+//------------------------------------------------------------------------
+// Find an item in an array, returns the key, or -1 if not found
+function FindInArray(array, x) {
+ for (var i = 0; i < array.length; i++) {
+ if (array[i] == x) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+// Delete an element from an array
+function DeleteArrayElement(array, x) {
+ var i = 0;
+ while (i < array.length && array[i] != x)
+ i++;
+ array.splice(i, 1);
+}
+
+// Clean up email address:
+// - remove extra spaces
+// - Surround name with quotes if it contains special characters
+// to check if we need " quotes
+// Note: do not use /g in the regular expression, otherwise the
+// regular expression cannot be reusable.
+var specialchars_re_ = /[()<>@,;:\\\".\[\]]/;
+
+//------------------------------------------------------------------------
+// Timeouts
+//
+// It is easy to forget to put a try/catch block around a timeout function,
+// and the result is an ugly user visible javascript error.
+// Also, it would be nice if a timeout associated with a window is
+// automatically cancelled when the user navigates away from that window.
+//
+// When storing timeouts in a window, we can't let that variable be renamed
+// since the window could be top.js, and renaming such a property could
+// clash with any of the variables/functions defined in top.js.
+//------------------------------------------------------------------------
+/**
+ * Sets a timeout safely.
+ * @param win the window object. If null is passed in, then a timeout if set
+ * on the js frame. If the window is closed, or freed, the timeout is
+ * automaticaaly cancelled
+ * @param fn the callback function: fn(win) will be called.
+ * @param ms number of ms the callback should be called later
+ */
+function SafeTimeout(win, fn, ms) {
+ if (!win) win = window;
+ if (!win._tm) {
+ win._tm = [];
+ }
+ var timeoutfn = SafeTimeoutFunction_(win, fn);
+ var id = win.setTimeout(timeoutfn, ms);
+
+ // Save the id so that it can be removed from the _tm array
+ timeoutfn.id = id;
+
+ // Safe the timeout in the _tm array
+ win._tm[id] = 1;
+
+ return id;
+}
+
+/** Creates a callback function for a timeout*/
+function SafeTimeoutFunction_(win, fn) {
+ var timeoutfn = function() {
+ try {
+ fn(win);
+
+ var t = win._tm;
+ if (t) {
+ delete t[timeoutfn.id];
+ }
+ } catch (e) {
+ DumpException(e);
+ }
+ };
+ return timeoutfn;
+}
+
+//------------------------------------------------------------------------
+// Misc
+//------------------------------------------------------------------------
+// Check if a value is defined
+function IsDefined(value) {
+ return (typeof value) != 'undefined';
+}
+
+function GetKeyCode(event) {
+ var code;
+ if (event.keyCode) {
+ code = event.keyCode;
+ } else if (event.which) {
+ code = event.which;
+ }
+ return code;
+}
« no previous file with comments | « appengine/monorail/static/js/framework/project-name-check.js ('k') | appengine/monorail/static/js/graveyard/geom.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698