http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/fontsizemonitor.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/fontsizemonitor.js b/externs/GCL/externs/goog/dom/fontsizemonitor.js new file mode 100644 index 0000000..6c7c8b4 --- /dev/null +++ b/externs/GCL/externs/goog/dom/fontsizemonitor.js @@ -0,0 +1,162 @@ +// Copyright 2005 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview A class that can be used to listen to font size changes. + * @author [email protected] (Erik Arvidsson) + */ + +goog.provide('goog.dom.FontSizeMonitor'); +goog.provide('goog.dom.FontSizeMonitor.EventType'); + +goog.require('goog.dom'); +goog.require('goog.dom.TagName'); +goog.require('goog.events'); +goog.require('goog.events.EventTarget'); +goog.require('goog.events.EventType'); +goog.require('goog.userAgent'); + + +// TODO(arv): Move this to goog.events instead. + + + +/** + * This class can be used to monitor changes in font size. Instances will + * dispatch a {@code goog.dom.FontSizeMonitor.EventType.CHANGE} event. + * Example usage: + * <pre> + * var fms = new goog.dom.FontSizeMonitor(); + * goog.events.listen(fms, goog.dom.FontSizeMonitor.EventType.CHANGE, + * function(e) { + * alert('Font size was changed'); + * }); + * </pre> + * @param {goog.dom.DomHelper=} opt_domHelper DOM helper object that is used to + * determine where to insert the DOM nodes used to determine when the font + * size changes. + * @constructor + * @extends {goog.events.EventTarget} + * @final + */ +goog.dom.FontSizeMonitor = function(opt_domHelper) { + goog.events.EventTarget.call(this); + + var dom = opt_domHelper || goog.dom.getDomHelper(); + + /** + * Offscreen iframe which we use to detect resize events. + * @type {Element} + * @private + */ + this.sizeElement_ = dom.createDom( + // The size of the iframe is expressed in em, which are font size relative + // which will cause the iframe to be resized when the font size changes. + // The actual values are not relevant as long as we can ensure that the + // iframe has a non zero size and is completely off screen. + goog.userAgent.IE ? goog.dom.TagName.DIV : goog.dom.TagName.IFRAME, { + 'style': 'position:absolute;width:9em;height:9em;top:-99em', + 'tabIndex': -1, + 'aria-hidden': 'true' + }); + var p = dom.getDocument().body; + p.insertBefore(this.sizeElement_, p.firstChild); + + /** + * The object that we listen to resize events on. + * @type {Element|Window} + * @private + */ + var resizeTarget = this.resizeTarget_ = + goog.userAgent.IE ? this.sizeElement_ : + goog.dom.getFrameContentWindow( + /** @type {HTMLIFrameElement} */ (this.sizeElement_)); + + // We need to open and close the document to get Firefox 2 to work. We must + // not do this for IE in case we are using HTTPS since accessing the document + // on an about:blank iframe in IE using HTTPS raises a Permission Denied + // error. + if (goog.userAgent.GECKO) { + var doc = resizeTarget.document; + doc.open(); + doc.close(); + } + + // Listen to resize event on the window inside the iframe. + goog.events.listen(resizeTarget, goog.events.EventType.RESIZE, + this.handleResize_, false, this); + + /** + * Last measured width of the iframe element. + * @type {number} + * @private + */ + this.lastWidth_ = this.sizeElement_.offsetWidth; +}; +goog.inherits(goog.dom.FontSizeMonitor, goog.events.EventTarget); + + +/** + * The event types that the FontSizeMonitor fires. + * @enum {string} + */ +goog.dom.FontSizeMonitor.EventType = { + // TODO(arv): Change value to 'change' after updating the callers. + CHANGE: 'fontsizechange' +}; + + +/** + * Constant for the change event. + * @type {string} + * @deprecated Use {@code goog.dom.FontSizeMonitor.EventType.CHANGE} instead. + */ +goog.dom.FontSizeMonitor.CHANGE_EVENT = + goog.dom.FontSizeMonitor.EventType.CHANGE; + + +/** @override */ +goog.dom.FontSizeMonitor.prototype.disposeInternal = function() { + goog.dom.FontSizeMonitor.superClass_.disposeInternal.call(this); + + goog.events.unlisten(this.resizeTarget_, goog.events.EventType.RESIZE, + this.handleResize_, false, this); + this.resizeTarget_ = null; + + // Firefox 2 crashes if the iframe is removed during the unload phase. + if (!goog.userAgent.GECKO || + goog.userAgent.isVersionOrHigher('1.9')) { + goog.dom.removeNode(this.sizeElement_); + } + delete this.sizeElement_; +}; + + +/** + * Handles the onresize event of the iframe and dispatches a change event in + * case its size really changed. + * @param {goog.events.BrowserEvent} e The event object. + * @private + */ +goog.dom.FontSizeMonitor.prototype.handleResize_ = function(e) { + // Only dispatch the event if the size really changed. Some newer browsers do + // not really change the font-size, instead they zoom the whole page. This + // does trigger window resize events on the iframe but the logical pixel size + // remains the same (the device pixel size changes but that is irrelevant). + var currentWidth = this.sizeElement_.offsetWidth; + if (this.lastWidth_ != currentWidth) { + this.lastWidth_ = currentWidth; + this.dispatchEvent(goog.dom.FontSizeMonitor.EventType.CHANGE); + } +};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/forms.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/forms.js b/externs/GCL/externs/goog/dom/forms.js new file mode 100644 index 0000000..75dc2e5 --- /dev/null +++ b/externs/GCL/externs/goog/dom/forms.js @@ -0,0 +1,417 @@ +// Copyright 2006 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Utilities for manipulating a form and elements. + * + * @author [email protected] (Erik Arvidsson) + */ + +goog.provide('goog.dom.forms'); + +goog.require('goog.dom.InputType'); +goog.require('goog.dom.TagName'); +goog.require('goog.structs.Map'); + + +/** + * Returns form data as a map of name to value arrays. This doesn't + * support file inputs. + * @param {HTMLFormElement} form The form. + * @return {!goog.structs.Map.<string, !Array.<string>>} A map of the form data + * as field name to arrays of values. + */ +goog.dom.forms.getFormDataMap = function(form) { + var map = new goog.structs.Map(); + goog.dom.forms.getFormDataHelper_(form, map, + goog.dom.forms.addFormDataToMap_); + return map; +}; + + +/** + * Returns the form data as an application/x-www-url-encoded string. This + * doesn't support file inputs. + * @param {HTMLFormElement} form The form. + * @return {string} An application/x-www-url-encoded string. + */ +goog.dom.forms.getFormDataString = function(form) { + var sb = []; + goog.dom.forms.getFormDataHelper_(form, sb, + goog.dom.forms.addFormDataToStringBuffer_); + return sb.join('&'); +}; + + +/** + * Returns the form data as a map or an application/x-www-url-encoded + * string. This doesn't support file inputs. + * @param {HTMLFormElement} form The form. + * @param {Object} result The object form data is being put in. + * @param {Function} fnAppend Function that takes {@code result}, an element + * name, and an element value, and adds the name/value pair to the result + * object. + * @private + */ +goog.dom.forms.getFormDataHelper_ = function(form, result, fnAppend) { + var els = form.elements; + for (var el, i = 0; el = els[i]; i++) { + if (// Make sure we don't include elements that are not part of the form. + // Some browsers include non-form elements. Check for 'form' property. + // See http://code.google.com/p/closure-library/issues/detail?id=227 + // and + // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#the-input-element + (el.form != form) || + el.disabled || + // HTMLFieldSetElement has a form property but no value. + el.tagName == goog.dom.TagName.FIELDSET) { + continue; + } + + var name = el.name; + switch (el.type.toLowerCase()) { + case goog.dom.InputType.FILE: + // file inputs are not supported + case goog.dom.InputType.SUBMIT: + case goog.dom.InputType.RESET: + case goog.dom.InputType.BUTTON: + // don't submit these + break; + case goog.dom.InputType.SELECT_MULTIPLE: + var values = goog.dom.forms.getValue(el); + if (values != null) { + for (var value, j = 0; value = values[j]; j++) { + fnAppend(result, name, value); + } + } + break; + default: + var value = goog.dom.forms.getValue(el); + if (value != null) { + fnAppend(result, name, value); + } + } + } + + // input[type=image] are not included in the elements collection + var inputs = form.getElementsByTagName(goog.dom.TagName.INPUT); + for (var input, i = 0; input = inputs[i]; i++) { + if (input.form == form && + input.type.toLowerCase() == goog.dom.InputType.IMAGE) { + name = input.name; + fnAppend(result, name, input.value); + fnAppend(result, name + '.x', '0'); + fnAppend(result, name + '.y', '0'); + } + } +}; + + +/** + * Adds the name/value pair to the map. + * @param {!goog.structs.Map.<string, !Array.<string>>} map The map to add to. + * @param {string} name The name. + * @param {string} value The value. + * @private + */ +goog.dom.forms.addFormDataToMap_ = function(map, name, value) { + var array = map.get(name); + if (!array) { + array = []; + map.set(name, array); + } + array.push(value); +}; + + +/** + * Adds a name/value pair to an string buffer array in the form 'name=value'. + * @param {Array<string>} sb The string buffer array for storing data. + * @param {string} name The name. + * @param {string} value The value. + * @private + */ +goog.dom.forms.addFormDataToStringBuffer_ = function(sb, name, value) { + sb.push(encodeURIComponent(name) + '=' + encodeURIComponent(value)); +}; + + +/** + * Whether the form has a file input. + * @param {HTMLFormElement} form The form. + * @return {boolean} Whether the form has a file input. + */ +goog.dom.forms.hasFileInput = function(form) { + var els = form.elements; + for (var el, i = 0; el = els[i]; i++) { + if (!el.disabled && el.type && + el.type.toLowerCase() == goog.dom.InputType.FILE) { + return true; + } + } + return false; +}; + + +/** + * Enables or disables either all elements in a form or a single form element. + * @param {Element} el The element, either a form or an element within a form. + * @param {boolean} disabled Whether the element should be disabled. + */ +goog.dom.forms.setDisabled = function(el, disabled) { + // disable all elements in a form + if (el.tagName == goog.dom.TagName.FORM) { + var els = el.elements; + for (var i = 0; el = els[i]; i++) { + goog.dom.forms.setDisabled(el, disabled); + } + } else { + // makes sure to blur buttons, multi-selects, and any elements which + // maintain keyboard/accessibility focus when disabled + if (disabled == true) { + el.blur(); + } + el.disabled = disabled; + } +}; + + +/** + * Focuses, and optionally selects the content of, a form element. + * @param {Element} el The form element. + */ +goog.dom.forms.focusAndSelect = function(el) { + el.focus(); + if (el.select) { + el.select(); + } +}; + + +/** + * Whether a form element has a value. + * @param {Element} el The element. + * @return {boolean} Whether the form has a value. + */ +goog.dom.forms.hasValue = function(el) { + var value = goog.dom.forms.getValue(el); + return !!value; +}; + + +/** + * Whether a named form field has a value. + * @param {HTMLFormElement} form The form element. + * @param {string} name Name of an input to the form. + * @return {boolean} Whether the form has a value. + */ +goog.dom.forms.hasValueByName = function(form, name) { + var value = goog.dom.forms.getValueByName(form, name); + return !!value; +}; + + +/** + * Gets the current value of any element with a type. + * @param {Element} el The element. + * @return {string|Array<string>|null} The current value of the element + * (or null). + */ +goog.dom.forms.getValue = function(el) { + var type = el.type; + if (!goog.isDef(type)) { + return null; + } + switch (type.toLowerCase()) { + case goog.dom.InputType.CHECKBOX: + case goog.dom.InputType.RADIO: + return goog.dom.forms.getInputChecked_(el); + case goog.dom.InputType.SELECT_ONE: + return goog.dom.forms.getSelectSingle_(el); + case goog.dom.InputType.SELECT_MULTIPLE: + return goog.dom.forms.getSelectMultiple_(el); + default: + return goog.isDef(el.value) ? el.value : null; + } +}; + + +/** + * Alias for goog.dom.form.element.getValue + * @type {Function} + * @deprecated Use {@link goog.dom.forms.getValue} instead. + * @suppress {missingProvide} + */ +goog.dom.$F = goog.dom.forms.getValue; + + +/** + * Returns the value of the named form field. In the case of radio buttons, + * returns the value of the checked button with the given name. + * + * @param {HTMLFormElement} form The form element. + * @param {string} name Name of an input to the form. + * + * @return {Array<string>|string|null} The value of the form element, or + * null if the form element does not exist or has no value. + */ +goog.dom.forms.getValueByName = function(form, name) { + var els = form.elements[name]; + + if (els) { + if (els.type) { + return goog.dom.forms.getValue(els); + } else { + for (var i = 0; i < els.length; i++) { + var val = goog.dom.forms.getValue(els[i]); + if (val) { + return val; + } + } + } + } + return null; +}; + + +/** + * Gets the current value of a checkable input element. + * @param {Element} el The element. + * @return {?string} The value of the form element (or null). + * @private + */ +goog.dom.forms.getInputChecked_ = function(el) { + return el.checked ? el.value : null; +}; + + +/** + * Gets the current value of a select-one element. + * @param {Element} el The element. + * @return {?string} The value of the form element (or null). + * @private + */ +goog.dom.forms.getSelectSingle_ = function(el) { + var selectedIndex = el.selectedIndex; + return selectedIndex >= 0 ? el.options[selectedIndex].value : null; +}; + + +/** + * Gets the current value of a select-multiple element. + * @param {Element} el The element. + * @return {Array<string>?} The value of the form element (or null). + * @private + */ +goog.dom.forms.getSelectMultiple_ = function(el) { + var values = []; + for (var option, i = 0; option = el.options[i]; i++) { + if (option.selected) { + values.push(option.value); + } + } + return values.length ? values : null; +}; + + +/** + * Sets the current value of any element with a type. + * @param {Element} el The element. + * @param {*=} opt_value The value to give to the element, which will be coerced + * by the browser in the default case using toString. This value should be + * an array for setting the value of select multiple elements. + */ +goog.dom.forms.setValue = function(el, opt_value) { + var type = el.type; + if (goog.isDef(type)) { + switch (type.toLowerCase()) { + case goog.dom.InputType.CHECKBOX: + case goog.dom.InputType.RADIO: + goog.dom.forms.setInputChecked_(el, + /** @type {string} */ (opt_value)); + break; + case goog.dom.InputType.SELECT_ONE: + goog.dom.forms.setSelectSingle_(el, + /** @type {string} */ (opt_value)); + break; + case goog.dom.InputType.SELECT_MULTIPLE: + goog.dom.forms.setSelectMultiple_(el, + /** @type {Array<string>} */ (opt_value)); + break; + default: + el.value = goog.isDefAndNotNull(opt_value) ? opt_value : ''; + } + } +}; + + +/** + * Sets a checkable input element's checked property. + * #TODO(user): This seems potentially unintuitive since it doesn't set + * the value property but my hunch is that the primary use case is to check a + * checkbox, not to reset its value property. + * @param {Element} el The element. + * @param {string|boolean=} opt_value The value, sets the element checked if + * val is set. + * @private + */ +goog.dom.forms.setInputChecked_ = function(el, opt_value) { + el.checked = opt_value; +}; + + +/** + * Sets the value of a select-one element. + * @param {Element} el The element. + * @param {string=} opt_value The value of the selected option element. + * @private + */ +goog.dom.forms.setSelectSingle_ = function(el, opt_value) { + // unset any prior selections + el.selectedIndex = -1; + if (goog.isString(opt_value)) { + for (var option, i = 0; option = el.options[i]; i++) { + if (option.value == opt_value) { + option.selected = true; + break; + } + } + } +}; + + +/** + * Sets the value of a select-multiple element. + * @param {Element} el The element. + * @param {Array<string>|string=} opt_value The value of the selected option + * element(s). + * @private + */ +goog.dom.forms.setSelectMultiple_ = function(el, opt_value) { + // reset string opt_values as an array + if (goog.isString(opt_value)) { + opt_value = [opt_value]; + } + for (var option, i = 0; option = el.options[i]; i++) { + // we have to reset the other options to false for select-multiple + option.selected = false; + if (opt_value) { + for (var value, j = 0; value = opt_value[j]; j++) { + if (option.value == value) { + option.selected = true; + } + } + } + } +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/fullscreen.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/fullscreen.js b/externs/GCL/externs/goog/dom/fullscreen.js new file mode 100644 index 0000000..1954213 --- /dev/null +++ b/externs/GCL/externs/goog/dom/fullscreen.js @@ -0,0 +1,144 @@ +// Copyright 2012 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Functions for managing full screen status of the DOM. + * + */ + +goog.provide('goog.dom.fullscreen'); +goog.provide('goog.dom.fullscreen.EventType'); + +goog.require('goog.dom'); +goog.require('goog.userAgent'); + + +/** + * Event types for full screen. + * @enum {string} + */ +goog.dom.fullscreen.EventType = { + /** Dispatched by the Document when the fullscreen status changes. */ + CHANGE: (function() { + if (goog.userAgent.WEBKIT) { + return 'webkitfullscreenchange'; + } + if (goog.userAgent.GECKO) { + return 'mozfullscreenchange'; + } + if (goog.userAgent.IE) { + return 'MSFullscreenChange'; + } + // Opera 12-14, and W3C standard (Draft): + // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html + return 'fullscreenchange'; + })() +}; + + +/** + * Determines if full screen is supported. + * @param {!goog.dom.DomHelper=} opt_domHelper The DomHelper for the DOM being + * queried. If not provided, use the current DOM. + * @return {boolean} True iff full screen is supported. + */ +goog.dom.fullscreen.isSupported = function(opt_domHelper) { + var doc = goog.dom.fullscreen.getDocument_(opt_domHelper); + var body = doc.body; + return !!(body.webkitRequestFullscreen || + (body.mozRequestFullScreen && doc.mozFullScreenEnabled) || + (body.msRequestFullscreen && doc.msFullscreenEnabled) || + (body.requestFullscreen && doc.fullscreenEnabled)); +}; + + +/** + * Requests putting the element in full screen. + * @param {!Element} element The element to put full screen. + */ +goog.dom.fullscreen.requestFullScreen = function(element) { + if (element.webkitRequestFullscreen) { + element.webkitRequestFullscreen(); + } else if (element.mozRequestFullScreen) { + element.mozRequestFullScreen(); + } else if (element.msRequestFullscreen) { + element.msRequestFullscreen(); + } else if (element.requestFullscreen) { + element.requestFullscreen(); + } +}; + + +/** + * Requests putting the element in full screen with full keyboard access. + * @param {!Element} element The element to put full screen. + */ +goog.dom.fullscreen.requestFullScreenWithKeys = function( + element) { + if (element.mozRequestFullScreenWithKeys) { + element.mozRequestFullScreenWithKeys(); + } else if (element.webkitRequestFullscreen) { + element.webkitRequestFullscreen(); + } else { + goog.dom.fullscreen.requestFullScreen(element); + } +}; + + +/** + * Exits full screen. + * @param {!goog.dom.DomHelper=} opt_domHelper The DomHelper for the DOM being + * queried. If not provided, use the current DOM. + */ +goog.dom.fullscreen.exitFullScreen = function(opt_domHelper) { + var doc = goog.dom.fullscreen.getDocument_(opt_domHelper); + if (doc.webkitCancelFullScreen) { + doc.webkitCancelFullScreen(); + } else if (doc.mozCancelFullScreen) { + doc.mozCancelFullScreen(); + } else if (doc.msExitFullscreen) { + doc.msExitFullscreen(); + } else if (doc.exitFullscreen) { + doc.exitFullscreen(); + } +}; + + +/** + * Determines if the document is full screen. + * @param {!goog.dom.DomHelper=} opt_domHelper The DomHelper for the DOM being + * queried. If not provided, use the current DOM. + * @return {boolean} Whether the document is full screen. + */ +goog.dom.fullscreen.isFullScreen = function(opt_domHelper) { + var doc = goog.dom.fullscreen.getDocument_(opt_domHelper); + // IE 11 doesn't have similar boolean property, so check whether + // document.msFullscreenElement is null instead. + return !!(doc.webkitIsFullScreen || doc.mozFullScreen || + doc.msFullscreenElement || doc.fullscreenElement); +}; + + +/** + * Gets the document object of the dom. + * @param {!goog.dom.DomHelper=} opt_domHelper The DomHelper for the DOM being + * queried. If not provided, use the current DOM. + * @return {!Document} The dom document. + * @private + */ +goog.dom.fullscreen.getDocument_ = function(opt_domHelper) { + return opt_domHelper ? + opt_domHelper.getDocument() : + goog.dom.getDomHelper().getDocument(); +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/iframe.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/iframe.js b/externs/GCL/externs/goog/dom/iframe.js new file mode 100644 index 0000000..a22b8b7 --- /dev/null +++ b/externs/GCL/externs/goog/dom/iframe.js @@ -0,0 +1,216 @@ +// Copyright 2008 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Utilities for creating and working with iframes + * cross-browser. + * @author [email protected] (Garry Boyer) + */ + + +goog.provide('goog.dom.iframe'); + +goog.require('goog.dom'); +goog.require('goog.dom.safe'); +goog.require('goog.html.SafeHtml'); +goog.require('goog.html.SafeStyle'); +goog.require('goog.html.legacyconversions'); +goog.require('goog.userAgent'); + + +/** + * Safe source for a blank iframe. + * + * Intentionally not about:blank, which gives mixed content warnings in IE6 + * over HTTPS. + * + * @type {string} + */ +goog.dom.iframe.BLANK_SOURCE = 'javascript:""'; + + +/** + * Safe source for a new blank iframe that may not cause a new load of the + * iframe. This is different from {@code goog.dom.iframe.BLANK_SOURCE} in that + * it will allow an iframe to be loaded synchronously in more browsers, notably + * Gecko, following the javascript protocol spec. + * + * NOTE: This should not be used to replace the source of an existing iframe. + * The new src value will be ignored, per the spec. + * + * Due to cross-browser differences, the load is not guaranteed to be + * synchronous. If code depends on the load of the iframe, + * then {@code goog.net.IframeLoadMonitor} or a similar technique should be + * used. + * + * According to + * http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#javascript-protocol + * the 'javascript:""' URL should trigger a new load of the iframe, which may be + * asynchronous. A void src, such as 'javascript:undefined', does not change + * the browsing context document's, and thus should not trigger another load. + * + * Intentionally not about:blank, which also triggers a load. + * + * NOTE: 'javascript:' URL handling spec compliance varies per browser. IE + * throws an error with 'javascript:undefined'. Webkit browsers will reload the + * iframe when setting this source on an existing iframe. + * + * @type {string} + */ +goog.dom.iframe.BLANK_SOURCE_NEW_FRAME = goog.userAgent.IE ? + 'javascript:""' : + 'javascript:undefined'; + + +/** + * Styles to help ensure an undecorated iframe. + * @type {string} + * @private + */ +goog.dom.iframe.STYLES_ = 'border:0;vertical-align:bottom;'; + + +/** + * Creates a completely blank iframe element. + * + * The iframe will not caused mixed-content warnings for IE6 under HTTPS. + * The iframe will also have no borders or padding, so that the styled width + * and height will be the actual width and height of the iframe. + * + * This function currently only attempts to create a blank iframe. There + * are no guarantees to the contents of the iframe or whether it is rendered + * in quirks mode. + * + * @param {goog.dom.DomHelper} domHelper The dom helper to use. + * @param {!goog.html.SafeStyle|string=} opt_styles CSS styles for the + * iframe. If possible pass a SafeStyle; string is supported for + * backwards-compatibility only and uses goog.html.legacyconversions. + * @return {!HTMLIFrameElement} A completely blank iframe. + */ +goog.dom.iframe.createBlank = function(domHelper, opt_styles) { + var styles; + if (goog.isString(opt_styles)) { + styles = goog.html.legacyconversions.safeStyleFromString(opt_styles) + .getTypedStringValue(); + } else if (opt_styles instanceof goog.html.SafeStyle) { + // SafeStyle has to be converted back to a string for now, since there's + // no safe alternative to createDom(). + styles = goog.html.SafeStyle.unwrap(opt_styles); + } else { // undefined. + styles = ''; + } + return /** @type {!HTMLIFrameElement} */ (domHelper.createDom('iframe', { + 'frameborder': 0, + // Since iframes are inline elements, we must align to bottom to + // compensate for the line descent. + 'style': goog.dom.iframe.STYLES_ + styles, + 'src': goog.dom.iframe.BLANK_SOURCE + })); +}; + + +/** + * Writes the contents of a blank iframe that has already been inserted + * into the document. If possible use {@link #writeSafeContent}, + * this function exists for backwards-compatibility only and uses + * goog.html.legacyconversions. + * @param {!HTMLIFrameElement} iframe An iframe with no contents, such as + * one created by goog.dom.iframe.createBlank, but already appended to + * a parent document. + * @param {string} content Content to write to the iframe, from doctype to + * the HTML close tag. + */ +goog.dom.iframe.writeContent = function(iframe, content) { + goog.dom.iframe.writeSafeContent( + iframe, goog.html.legacyconversions.safeHtmlFromString(content)); +}; + + +/** + * Writes the contents of a blank iframe that has already been inserted + * into the document. + * @param {!HTMLIFrameElement} iframe An iframe with no contents, such as + * one created by {@link #createBlank}, but already appended to + * a parent document. + * @param {!goog.html.SafeHtml} content Content to write to the iframe, + * from doctype to the HTML close tag. + */ +goog.dom.iframe.writeSafeContent = function(iframe, content) { + var doc = goog.dom.getFrameContentDocument(iframe); + doc.open(); + goog.dom.safe.documentWrite(doc, content); + doc.close(); +}; + + +// TODO(gboyer): Provide a higher-level API for the most common use case, so +// that you can just provide a list of stylesheets and some content HTML. +/** + * Creates a same-domain iframe containing preloaded content. + * + * This is primarily useful for DOM sandboxing. One use case is to embed + * a trusted Javascript app with potentially conflicting CSS styles. The + * second case is to reduce the cost of layout passes by the browser -- for + * example, you can perform sandbox sizing of characters in an iframe while + * manipulating a heavy DOM in the main window. The iframe and parent frame + * can access each others' properties and functions without restriction. + * + * @param {!Element} parentElement The parent element in which to append the + * iframe. + * @param {!goog.html.SafeHtml|string=} opt_headContents Contents to go into + * the iframe's head. If possible pass a SafeHtml; string is supported for + * backwards-compatibility only and uses goog.html.legacyconversions. + * @param {!goog.html.SafeHtml|string=} opt_bodyContents Contents to go into + * the iframe's body. If possible pass a SafeHtml; string is supported for + * backwards-compatibility only and uses goog.html.legacyconversions. + * @param {!goog.html.SafeStyle|string=} opt_styles CSS styles for the iframe + * itself, before adding to the parent element. If possible pass a + * SafeStyle; string is supported for backwards-compatibility only and + * uses goog.html.legacyconversions. + * @param {boolean=} opt_quirks Whether to use quirks mode (false by default). + * @return {!HTMLIFrameElement} An iframe that has the specified contents. + */ +goog.dom.iframe.createWithContent = function( + parentElement, opt_headContents, opt_bodyContents, opt_styles, opt_quirks) { + var domHelper = goog.dom.getDomHelper(parentElement); + + if (goog.isString(opt_headContents)) { + opt_headContents = + goog.html.legacyconversions.safeHtmlFromString(opt_headContents); + } + if (goog.isString(opt_bodyContents)) { + opt_bodyContents = + goog.html.legacyconversions.safeHtmlFromString(opt_bodyContents); + } + if (goog.isString(opt_styles)) { + opt_styles = + goog.html.legacyconversions.safeStyleFromString(opt_styles); + } + + var content = goog.html.SafeHtml.create('html', {}, goog.html.SafeHtml.concat( + goog.html.SafeHtml.create('head', {}, opt_headContents), + goog.html.SafeHtml.create('body', {}, opt_bodyContents))); + if (!opt_quirks) { + content = + goog.html.SafeHtml.concat(goog.html.SafeHtml.DOCTYPE_HTML, content); + } + + var iframe = goog.dom.iframe.createBlank(domHelper, opt_styles); + + // Cannot manipulate iframe content until it is in a document. + parentElement.appendChild(iframe); + goog.dom.iframe.writeSafeContent(iframe, content); + + return iframe; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/inputtype.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/inputtype.js b/externs/GCL/externs/goog/dom/inputtype.js new file mode 100644 index 0000000..f5db6c8 --- /dev/null +++ b/externs/GCL/externs/goog/dom/inputtype.js @@ -0,0 +1,66 @@ +// Copyright 2015 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Defines the goog.dom.InputType enum. This enumerates + * all input element types (for INPUT, BUTTON, SELECT and TEXTAREA + * elements) in either the the W3C HTML 4.01 index of elements or the + * HTML5 draft specification. + * + * References: + * http://www.w3.org/TR/html401/sgml/dtd.html#InputType + * http://www.w3.org/TR/html-markup/input.html#input + * https://html.spec.whatwg.org/multipage/forms.html#dom-input-type + * https://html.spec.whatwg.org/multipage/forms.html#dom-button-type + * https://html.spec.whatwg.org/multipage/forms.html#dom-select-type + * https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-type + * + */ +goog.provide('goog.dom.InputType'); + + +/** + * Enum of all input types (for INPUT, BUTTON, SELECT and TEXTAREA elements) + * specified by the W3C HTML4.01 and HTML5 specifications. + * @enum {string} + */ +goog.dom.InputType = { + BUTTON: 'button', + CHECKBOX: 'checkbox', + COLOR: 'color', + DATE: 'date', + DATETIME: 'datetime', + DATETIME_LOCAL: 'datetime-local', + EMAIL: 'email', + FILE: 'file', + HIDDEN: 'hidden', + IMAGE: 'image', + MENU: 'menu', + MONTH: 'month', + NUMBER: 'number', + PASSWORD: 'password', + RADIO: 'radio', + RANGE: 'range', + RESET: 'reset', + SEARCH: 'search', + SELECT_MULTIPLE: 'select-multiple', + SELECT_ONE: 'select-one', + SUBMIT: 'submit', + TEL: 'tel', + TEXT: 'text', + TEXTAREA: 'textarea', + TIME: 'time', + URL: 'url', + WEEK: 'week' +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/iter.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/iter.js b/externs/GCL/externs/goog/dom/iter.js new file mode 100644 index 0000000..7516414 --- /dev/null +++ b/externs/GCL/externs/goog/dom/iter.js @@ -0,0 +1,129 @@ +// Copyright 2008 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Iterators over DOM nodes. + * + * @author [email protected] (Robby Walker) + */ + +goog.provide('goog.dom.iter.AncestorIterator'); +goog.provide('goog.dom.iter.ChildIterator'); +goog.provide('goog.dom.iter.SiblingIterator'); + +goog.require('goog.iter.Iterator'); +goog.require('goog.iter.StopIteration'); + + + +/** + * Iterator over a Node's siblings. + * @param {Node} node The node to start with. + * @param {boolean=} opt_includeNode Whether to return the given node as the + * first return value from next. + * @param {boolean=} opt_reverse Whether to traverse siblings in reverse + * document order. + * @constructor + * @extends {goog.iter.Iterator} + */ +goog.dom.iter.SiblingIterator = function(node, opt_includeNode, opt_reverse) { + /** + * The current node, or null if iteration is finished. + * @type {Node} + * @private + */ + this.node_ = node; + + /** + * Whether to iterate in reverse. + * @type {boolean} + * @private + */ + this.reverse_ = !!opt_reverse; + + if (node && !opt_includeNode) { + this.next(); + } +}; +goog.inherits(goog.dom.iter.SiblingIterator, goog.iter.Iterator); + + +/** @override */ +goog.dom.iter.SiblingIterator.prototype.next = function() { + var node = this.node_; + if (!node) { + throw goog.iter.StopIteration; + } + this.node_ = this.reverse_ ? node.previousSibling : node.nextSibling; + return node; +}; + + + +/** + * Iterator over an Element's children. + * @param {Element} element The element to iterate over. + * @param {boolean=} opt_reverse Optionally traverse children from last to + * first. + * @param {number=} opt_startIndex Optional starting index. + * @constructor + * @extends {goog.dom.iter.SiblingIterator} + * @final + */ +goog.dom.iter.ChildIterator = function(element, opt_reverse, opt_startIndex) { + if (!goog.isDef(opt_startIndex)) { + opt_startIndex = opt_reverse && element.childNodes.length ? + element.childNodes.length - 1 : 0; + } + goog.dom.iter.SiblingIterator.call(this, element.childNodes[opt_startIndex], + true, opt_reverse); +}; +goog.inherits(goog.dom.iter.ChildIterator, goog.dom.iter.SiblingIterator); + + + +/** + * Iterator over a Node's ancestors, stopping after the document body. + * @param {Node} node The node to start with. + * @param {boolean=} opt_includeNode Whether to return the given node as the + * first return value from next. + * @constructor + * @extends {goog.iter.Iterator} + * @final + */ +goog.dom.iter.AncestorIterator = function(node, opt_includeNode) { + /** + * The current node, or null if iteration is finished. + * @type {Node} + * @private + */ + this.node_ = node; + + if (node && !opt_includeNode) { + this.next(); + } +}; +goog.inherits(goog.dom.iter.AncestorIterator, goog.iter.Iterator); + + +/** @override */ +goog.dom.iter.AncestorIterator.prototype.next = function() { + var node = this.node_; + if (!node) { + throw goog.iter.StopIteration; + } + this.node_ = node.parentNode; + return node; +}; + http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/multirange.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/multirange.js b/externs/GCL/externs/goog/dom/multirange.js new file mode 100644 index 0000000..9a57d25 --- /dev/null +++ b/externs/GCL/externs/goog/dom/multirange.js @@ -0,0 +1,510 @@ +// Copyright 2008 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Utilities for working with W3C multi-part ranges. + * + * @author [email protected] (Robby Walker) + */ + + +goog.provide('goog.dom.MultiRange'); +goog.provide('goog.dom.MultiRangeIterator'); + +goog.require('goog.array'); +goog.require('goog.dom.AbstractMultiRange'); +goog.require('goog.dom.AbstractRange'); +goog.require('goog.dom.RangeIterator'); +goog.require('goog.dom.RangeType'); +goog.require('goog.dom.SavedRange'); +goog.require('goog.dom.TextRange'); +goog.require('goog.iter.StopIteration'); +goog.require('goog.log'); + + + +/** + * Creates a new multi part range with no properties. Do not use this + * constructor: use one of the goog.dom.Range.createFrom* methods instead. + * @constructor + * @extends {goog.dom.AbstractMultiRange} + * @final + */ +goog.dom.MultiRange = function() { + /** + * Logging object. + * @private {goog.log.Logger} + */ + this.logger_ = goog.log.getLogger('goog.dom.MultiRange'); + + /** + * Array of browser sub-ranges comprising this multi-range. + * @private {Array<Range>} + */ + this.browserRanges_ = []; + + /** + * Lazily initialized array of range objects comprising this multi-range. + * @private {Array<goog.dom.TextRange>} + */ + this.ranges_ = []; + + /** + * Lazily computed sorted version of ranges_, sorted by start point. + * @private {Array<goog.dom.TextRange>?} + */ + this.sortedRanges_ = null; + + /** + * Lazily computed container node. + * @private {Node} + */ + this.container_ = null; +}; +goog.inherits(goog.dom.MultiRange, goog.dom.AbstractMultiRange); + + +/** + * Creates a new range wrapper from the given browser selection object. Do not + * use this method directly - please use goog.dom.Range.createFrom* instead. + * @param {Selection} selection The browser selection object. + * @return {!goog.dom.MultiRange} A range wrapper object. + */ +goog.dom.MultiRange.createFromBrowserSelection = function(selection) { + var range = new goog.dom.MultiRange(); + for (var i = 0, len = selection.rangeCount; i < len; i++) { + range.browserRanges_.push(selection.getRangeAt(i)); + } + return range; +}; + + +/** + * Creates a new range wrapper from the given browser ranges. Do not + * use this method directly - please use goog.dom.Range.createFrom* instead. + * @param {Array<Range>} browserRanges The browser ranges. + * @return {!goog.dom.MultiRange} A range wrapper object. + */ +goog.dom.MultiRange.createFromBrowserRanges = function(browserRanges) { + var range = new goog.dom.MultiRange(); + range.browserRanges_ = goog.array.clone(browserRanges); + return range; +}; + + +/** + * Creates a new range wrapper from the given goog.dom.TextRange objects. Do + * not use this method directly - please use goog.dom.Range.createFrom* instead. + * @param {Array<goog.dom.TextRange>} textRanges The text range objects. + * @return {!goog.dom.MultiRange} A range wrapper object. + */ +goog.dom.MultiRange.createFromTextRanges = function(textRanges) { + var range = new goog.dom.MultiRange(); + range.ranges_ = textRanges; + range.browserRanges_ = goog.array.map(textRanges, function(range) { + return range.getBrowserRangeObject(); + }); + return range; +}; + + +// Method implementations + + +/** + * Clears cached values. Should be called whenever this.browserRanges_ is + * modified. + * @private + */ +goog.dom.MultiRange.prototype.clearCachedValues_ = function() { + this.ranges_ = []; + this.sortedRanges_ = null; + this.container_ = null; +}; + + +/** + * @return {!goog.dom.MultiRange} A clone of this range. + * @override + */ +goog.dom.MultiRange.prototype.clone = function() { + return goog.dom.MultiRange.createFromBrowserRanges(this.browserRanges_); +}; + + +/** @override */ +goog.dom.MultiRange.prototype.getType = function() { + return goog.dom.RangeType.MULTI; +}; + + +/** @override */ +goog.dom.MultiRange.prototype.getBrowserRangeObject = function() { + // NOTE(robbyw): This method does not make sense for multi-ranges. + if (this.browserRanges_.length > 1) { + goog.log.warning(this.logger_, + 'getBrowserRangeObject called on MultiRange with more than 1 range'); + } + return this.browserRanges_[0]; +}; + + +/** @override */ +goog.dom.MultiRange.prototype.setBrowserRangeObject = function(nativeRange) { + // TODO(robbyw): Look in to adding setBrowserSelectionObject. + return false; +}; + + +/** @override */ +goog.dom.MultiRange.prototype.getTextRangeCount = function() { + return this.browserRanges_.length; +}; + + +/** @override */ +goog.dom.MultiRange.prototype.getTextRange = function(i) { + if (!this.ranges_[i]) { + this.ranges_[i] = goog.dom.TextRange.createFromBrowserRange( + this.browserRanges_[i]); + } + return this.ranges_[i]; +}; + + +/** @override */ +goog.dom.MultiRange.prototype.getContainer = function() { + if (!this.container_) { + var nodes = []; + for (var i = 0, len = this.getTextRangeCount(); i < len; i++) { + nodes.push(this.getTextRange(i).getContainer()); + } + this.container_ = goog.dom.findCommonAncestor.apply(null, nodes); + } + return this.container_; +}; + + +/** + * @return {!Array<goog.dom.TextRange>} An array of sub-ranges, sorted by start + * point. + */ +goog.dom.MultiRange.prototype.getSortedRanges = function() { + if (!this.sortedRanges_) { + this.sortedRanges_ = this.getTextRanges(); + this.sortedRanges_.sort(function(a, b) { + var aStartNode = a.getStartNode(); + var aStartOffset = a.getStartOffset(); + var bStartNode = b.getStartNode(); + var bStartOffset = b.getStartOffset(); + + if (aStartNode == bStartNode && aStartOffset == bStartOffset) { + return 0; + } + + return goog.dom.Range.isReversed(aStartNode, aStartOffset, bStartNode, + bStartOffset) ? 1 : -1; + }); + } + return this.sortedRanges_; +}; + + +/** @override */ +goog.dom.MultiRange.prototype.getStartNode = function() { + return this.getSortedRanges()[0].getStartNode(); +}; + + +/** @override */ +goog.dom.MultiRange.prototype.getStartOffset = function() { + return this.getSortedRanges()[0].getStartOffset(); +}; + + +/** @override */ +goog.dom.MultiRange.prototype.getEndNode = function() { + // NOTE(robbyw): This may return the wrong node if any subranges overlap. + return goog.array.peek(this.getSortedRanges()).getEndNode(); +}; + + +/** @override */ +goog.dom.MultiRange.prototype.getEndOffset = function() { + // NOTE(robbyw): This may return the wrong value if any subranges overlap. + return goog.array.peek(this.getSortedRanges()).getEndOffset(); +}; + + +/** @override */ +goog.dom.MultiRange.prototype.isRangeInDocument = function() { + return goog.array.every(this.getTextRanges(), function(range) { + return range.isRangeInDocument(); + }); +}; + + +/** @override */ +goog.dom.MultiRange.prototype.isCollapsed = function() { + return this.browserRanges_.length == 0 || + this.browserRanges_.length == 1 && this.getTextRange(0).isCollapsed(); +}; + + +/** @override */ +goog.dom.MultiRange.prototype.getText = function() { + return goog.array.map(this.getTextRanges(), function(range) { + return range.getText(); + }).join(''); +}; + + +/** @override */ +goog.dom.MultiRange.prototype.getHtmlFragment = function() { + return this.getValidHtml(); +}; + + +/** @override */ +goog.dom.MultiRange.prototype.getValidHtml = function() { + // NOTE(robbyw): This does not behave well if the sub-ranges overlap. + return goog.array.map(this.getTextRanges(), function(range) { + return range.getValidHtml(); + }).join(''); +}; + + +/** @override */ +goog.dom.MultiRange.prototype.getPastableHtml = function() { + // TODO(robbyw): This should probably do something smart like group TR and TD + // selections in to the same table. + return this.getValidHtml(); +}; + + +/** @override */ +goog.dom.MultiRange.prototype.__iterator__ = function(opt_keys) { + return new goog.dom.MultiRangeIterator(this); +}; + + +// RANGE ACTIONS + + +/** @override */ +goog.dom.MultiRange.prototype.select = function() { + var selection = goog.dom.AbstractRange.getBrowserSelectionForWindow( + this.getWindow()); + selection.removeAllRanges(); + for (var i = 0, len = this.getTextRangeCount(); i < len; i++) { + selection.addRange(this.getTextRange(i).getBrowserRangeObject()); + } +}; + + +/** @override */ +goog.dom.MultiRange.prototype.removeContents = function() { + goog.array.forEach(this.getTextRanges(), function(range) { + range.removeContents(); + }); +}; + + +// SAVE/RESTORE + + +/** @override */ +goog.dom.MultiRange.prototype.saveUsingDom = function() { + return new goog.dom.DomSavedMultiRange_(this); +}; + + +// RANGE MODIFICATION + + +/** + * Collapses this range to a single point, either the first or last point + * depending on the parameter. This will result in the number of ranges in this + * multi range becoming 1. + * @param {boolean} toAnchor Whether to collapse to the anchor. + * @override + */ +goog.dom.MultiRange.prototype.collapse = function(toAnchor) { + if (!this.isCollapsed()) { + var range = toAnchor ? this.getTextRange(0) : this.getTextRange( + this.getTextRangeCount() - 1); + + this.clearCachedValues_(); + range.collapse(toAnchor); + this.ranges_ = [range]; + this.sortedRanges_ = [range]; + this.browserRanges_ = [range.getBrowserRangeObject()]; + } +}; + + +// SAVED RANGE OBJECTS + + + +/** + * A SavedRange implementation using DOM endpoints. + * @param {goog.dom.MultiRange} range The range to save. + * @constructor + * @extends {goog.dom.SavedRange} + * @private + */ +goog.dom.DomSavedMultiRange_ = function(range) { + /** + * Array of saved ranges. + * @type {Array<goog.dom.SavedRange>} + * @private + */ + this.savedRanges_ = goog.array.map(range.getTextRanges(), function(range) { + return range.saveUsingDom(); + }); +}; +goog.inherits(goog.dom.DomSavedMultiRange_, goog.dom.SavedRange); + + +/** + * @return {!goog.dom.MultiRange} The restored range. + * @override + */ +goog.dom.DomSavedMultiRange_.prototype.restoreInternal = function() { + var ranges = goog.array.map(this.savedRanges_, function(savedRange) { + return savedRange.restore(); + }); + return goog.dom.MultiRange.createFromTextRanges(ranges); +}; + + +/** @override */ +goog.dom.DomSavedMultiRange_.prototype.disposeInternal = function() { + goog.dom.DomSavedMultiRange_.superClass_.disposeInternal.call(this); + + goog.array.forEach(this.savedRanges_, function(savedRange) { + savedRange.dispose(); + }); + delete this.savedRanges_; +}; + + +// RANGE ITERATION + + + +/** + * Subclass of goog.dom.TagIterator that iterates over a DOM range. It + * adds functions to determine the portion of each text node that is selected. + * + * @param {goog.dom.MultiRange} range The range to traverse. + * @constructor + * @extends {goog.dom.RangeIterator} + * @final + */ +goog.dom.MultiRangeIterator = function(range) { + /** + * The list of range iterators left to traverse. + * @private {Array<goog.dom.RangeIterator>} + */ + this.iterators_ = null; + + /** + * The index of the current sub-iterator being traversed. + * @private {number} + */ + this.currentIdx_ = 0; + + if (range) { + this.iterators_ = goog.array.map( + range.getSortedRanges(), + function(r) { + return goog.iter.toIterator(r); + }); + } + + goog.dom.MultiRangeIterator.base( + this, 'constructor', range ? this.getStartNode() : null, false); +}; +goog.inherits(goog.dom.MultiRangeIterator, goog.dom.RangeIterator); + + +/** @override */ +goog.dom.MultiRangeIterator.prototype.getStartTextOffset = function() { + return this.iterators_[this.currentIdx_].getStartTextOffset(); +}; + + +/** @override */ +goog.dom.MultiRangeIterator.prototype.getEndTextOffset = function() { + return this.iterators_[this.currentIdx_].getEndTextOffset(); +}; + + +/** @override */ +goog.dom.MultiRangeIterator.prototype.getStartNode = function() { + return this.iterators_[0].getStartNode(); +}; + + +/** @override */ +goog.dom.MultiRangeIterator.prototype.getEndNode = function() { + return goog.array.peek(this.iterators_).getEndNode(); +}; + + +/** @override */ +goog.dom.MultiRangeIterator.prototype.isLast = function() { + return this.iterators_[this.currentIdx_].isLast(); +}; + + +/** @override */ +goog.dom.MultiRangeIterator.prototype.next = function() { + /** @preserveTry */ + try { + var it = this.iterators_[this.currentIdx_]; + var next = it.next(); + this.setPosition(it.node, it.tagType, it.depth); + return next; + } catch (ex) { + if (ex !== goog.iter.StopIteration || + this.iterators_.length - 1 == this.currentIdx_) { + throw ex; + } else { + // In case we got a StopIteration, increment counter and try again. + this.currentIdx_++; + return this.next(); + } + } +}; + + +/** @override */ +goog.dom.MultiRangeIterator.prototype.copyFrom = function(other) { + this.iterators_ = goog.array.clone(other.iterators_); + goog.dom.MultiRangeIterator.superClass_.copyFrom.call(this, other); +}; + + +/** + * @return {!goog.dom.MultiRangeIterator} An identical iterator. + * @override + */ +goog.dom.MultiRangeIterator.prototype.clone = function() { + var copy = new goog.dom.MultiRangeIterator(null); + copy.copyFrom(this); + return copy; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/nodeiterator.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/nodeiterator.js b/externs/GCL/externs/goog/dom/nodeiterator.js new file mode 100644 index 0000000..bca563c --- /dev/null +++ b/externs/GCL/externs/goog/dom/nodeiterator.js @@ -0,0 +1,87 @@ +// Copyright 2008 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Iterator subclass for DOM tree traversal. + * + * @author [email protected] (Robby Walker) + */ + +goog.provide('goog.dom.NodeIterator'); + +goog.require('goog.dom.TagIterator'); + + + +/** + * A DOM tree traversal iterator. + * + * Starting with the given node, the iterator walks the DOM in order, reporting + * events for each node. The iterator acts as a prefix iterator: + * + * <pre> + * <div>1<span>2</span>3</div> + * </pre> + * + * Will return the following nodes: + * + * <code>[div, 1, span, 2, 3]</code> + * + * With the following depths + * + * <code>[1, 1, 2, 2, 1]</code> + * + * Imagining <code>|</code> represents iterator position, the traversal stops at + * each of the following locations: + * + * <pre><div>|1|<span>|2|</span>3|</div></pre> + * + * The iterator can also be used in reverse mode, which will return the nodes + * and states in the opposite order. The depths will be slightly different + * since, like in normal mode, the depth is computed *after* the last move. + * + * Lastly, it is possible to create an iterator that is unconstrained, meaning + * that it will continue iterating until the end of the document instead of + * until exiting the start node. + * + * @param {Node=} opt_node The start node. Defaults to an empty iterator. + * @param {boolean=} opt_reversed Whether to traverse the tree in reverse. + * @param {boolean=} opt_unconstrained Whether the iterator is not constrained + * to the starting node and its children. + * @param {number=} opt_depth The starting tree depth. + * @constructor + * @extends {goog.dom.TagIterator} + * @final + */ +goog.dom.NodeIterator = function(opt_node, opt_reversed, + opt_unconstrained, opt_depth) { + goog.dom.TagIterator.call(this, opt_node, opt_reversed, opt_unconstrained, + null, opt_depth); +}; +goog.inherits(goog.dom.NodeIterator, goog.dom.TagIterator); + + +/** + * Moves to the next position in the DOM tree. + * @return {Node} Returns the next node, or throws a goog.iter.StopIteration + * exception if the end of the iterator's range has been reached. + * @override + */ +goog.dom.NodeIterator.prototype.next = function() { + do { + goog.dom.NodeIterator.superClass_.next.call(this); + } while (this.isEndTag()); + + return this.node; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/nodeoffset.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/nodeoffset.js b/externs/GCL/externs/goog/dom/nodeoffset.js new file mode 100644 index 0000000..9a65dbe --- /dev/null +++ b/externs/GCL/externs/goog/dom/nodeoffset.js @@ -0,0 +1,114 @@ +// Copyright 2005 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Object to store the offset from one node to another in a way + * that works on any similar DOM structure regardless of whether it is the same + * actual nodes. + * + * @author [email protected] (Robby Walker) + */ + +goog.provide('goog.dom.NodeOffset'); + +goog.require('goog.Disposable'); +goog.require('goog.dom.TagName'); + + + +/** + * Object to store the offset from one node to another in a way that works on + * any similar DOM structure regardless of whether it is the same actual nodes. + * @param {Node} node The node to get the offset for. + * @param {Node} baseNode The node to calculate the offset from. + * @extends {goog.Disposable} + * @constructor + * @final + */ +goog.dom.NodeOffset = function(node, baseNode) { + goog.Disposable.call(this); + + /** + * A stack of childNode offsets. + * @type {Array<number>} + * @private + */ + this.offsetStack_ = []; + + /** + * A stack of childNode names. + * @type {Array<string>} + * @private + */ + this.nameStack_ = []; + + while (node && node.nodeName != goog.dom.TagName.BODY && node != baseNode) { + // Compute the sibling offset. + var siblingOffset = 0; + var sib = node.previousSibling; + while (sib) { + sib = sib.previousSibling; + ++siblingOffset; + } + this.offsetStack_.unshift(siblingOffset); + this.nameStack_.unshift(node.nodeName); + + node = node.parentNode; + } +}; +goog.inherits(goog.dom.NodeOffset, goog.Disposable); + + +/** + * @return {string} A string representation of this object. + * @override + */ +goog.dom.NodeOffset.prototype.toString = function() { + var strs = []; + var name; + for (var i = 0; name = this.nameStack_[i]; i++) { + strs.push(this.offsetStack_[i] + ',' + name); + } + return strs.join('\n'); +}; + + +/** + * Walk the dom and find the node relative to baseNode. Returns null on + * failure. + * @param {Node} baseNode The node to start walking from. Should be equivalent + * to the node passed in to the constructor, in that it should have the + * same contents. + * @return {Node} The node relative to baseNode, or null on failure. + */ +goog.dom.NodeOffset.prototype.findTargetNode = function(baseNode) { + var name; + var curNode = baseNode; + for (var i = 0; name = this.nameStack_[i]; ++i) { + curNode = curNode.childNodes[this.offsetStack_[i]]; + + // Sanity check and make sure the element names match. + if (!curNode || curNode.nodeName != name) { + return null; + } + } + return curNode; +}; + + +/** @override */ +goog.dom.NodeOffset.prototype.disposeInternal = function() { + delete this.offsetStack_; + delete this.nameStack_; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/nodetype.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/nodetype.js b/externs/GCL/externs/goog/dom/nodetype.js new file mode 100644 index 0000000..cccb470 --- /dev/null +++ b/externs/GCL/externs/goog/dom/nodetype.js @@ -0,0 +1,48 @@ +// Copyright 2006 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Definition of goog.dom.NodeType. + */ + +goog.provide('goog.dom.NodeType'); + + +/** + * Constants for the nodeType attribute in the Node interface. + * + * These constants match those specified in the Node interface. These are + * usually present on the Node object in recent browsers, but not in older + * browsers (specifically, early IEs) and thus are given here. + * + * In some browsers (early IEs), these are not defined on the Node object, + * so they are provided here. + * + * See http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247 + * @enum {number} + */ +goog.dom.NodeType = { + ELEMENT: 1, + ATTRIBUTE: 2, + TEXT: 3, + CDATA_SECTION: 4, + ENTITY_REFERENCE: 5, + ENTITY: 6, + PROCESSING_INSTRUCTION: 7, + COMMENT: 8, + DOCUMENT: 9, + DOCUMENT_TYPE: 10, + DOCUMENT_FRAGMENT: 11, + NOTATION: 12 +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/abstractpattern.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/pattern/abstractpattern.js b/externs/GCL/externs/goog/dom/pattern/abstractpattern.js new file mode 100644 index 0000000..e785f76 --- /dev/null +++ b/externs/GCL/externs/goog/dom/pattern/abstractpattern.js @@ -0,0 +1,58 @@ +// Copyright 2007 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview DOM pattern base class. + * + * @author [email protected] (Robby Walker) + */ + +goog.provide('goog.dom.pattern.AbstractPattern'); + +goog.require('goog.dom.pattern.MatchType'); + + + +/** + * Base pattern class for DOM matching. + * + * @constructor + */ +goog.dom.pattern.AbstractPattern = function() { + /** + * The first node matched by this pattern. + * @type {Node} + */ + this.matchedNode = null; +}; + + +/** + * Reset any internal state this pattern keeps. + */ +goog.dom.pattern.AbstractPattern.prototype.reset = function() { + // The base implementation does nothing. +}; + + +/** + * Test whether this pattern matches the given token. + * + * @param {Node} token Token to match against. + * @param {goog.dom.TagWalkType} type The type of token. + * @return {goog.dom.pattern.MatchType} {@code MATCH} if the pattern matches. + */ +goog.dom.pattern.AbstractPattern.prototype.matchToken = function(token, type) { + return goog.dom.pattern.MatchType.NO_MATCH; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/allchildren.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/pattern/allchildren.js b/externs/GCL/externs/goog/dom/pattern/allchildren.js new file mode 100644 index 0000000..36abae4 --- /dev/null +++ b/externs/GCL/externs/goog/dom/pattern/allchildren.js @@ -0,0 +1,72 @@ +// Copyright 2007 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview DOM pattern to match any children of a tag. + * + * @author [email protected] (Robby Walker) + */ + +goog.provide('goog.dom.pattern.AllChildren'); + +goog.require('goog.dom.pattern.AbstractPattern'); +goog.require('goog.dom.pattern.MatchType'); + + + +/** + * Pattern object that matches any nodes at or below the current tree depth. + * + * @constructor + * @extends {goog.dom.pattern.AbstractPattern} + */ +goog.dom.pattern.AllChildren = function() { + /** + * Tracks the matcher's depth to detect the end of the tag. + * + * @private {number} + */ + this.depth_ = 0; +}; +goog.inherits(goog.dom.pattern.AllChildren, goog.dom.pattern.AbstractPattern); + + +/** + * Test whether the given token is on the same level. + * + * @param {Node} token Token to match against. + * @param {goog.dom.TagWalkType} type The type of token. + * @return {goog.dom.pattern.MatchType} {@code MATCHING} if the token is on the + * same level or deeper and {@code BACKTRACK_MATCH} if not. + * @override + */ +goog.dom.pattern.AllChildren.prototype.matchToken = function(token, type) { + this.depth_ += type; + + if (this.depth_ >= 0) { + return goog.dom.pattern.MatchType.MATCHING; + } else { + this.depth_ = 0; + return goog.dom.pattern.MatchType.BACKTRACK_MATCH; + } +}; + + +/** + * Reset any internal state this pattern keeps. + * @override + */ +goog.dom.pattern.AllChildren.prototype.reset = function() { + this.depth_ = 0; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/callback/callback.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/pattern/callback/callback.js b/externs/GCL/externs/goog/dom/pattern/callback/callback.js new file mode 100644 index 0000000..7d7aa60 --- /dev/null +++ b/externs/GCL/externs/goog/dom/pattern/callback/callback.js @@ -0,0 +1,82 @@ +// Copyright 2007 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Useful callback functions for the DOM matcher. + * + * @author [email protected] (Robby Walker) + */ + +goog.provide('goog.dom.pattern.callback'); + +goog.require('goog.dom'); +goog.require('goog.dom.TagWalkType'); +goog.require('goog.iter'); + + +/** + * Callback function for use in {@link goog.dom.pattern.Matcher.addPattern} + * that removes the matched node from the tree. Should be used in conjunciton + * with a {@link goog.dom.pattern.StartTag} pattern. + * + * @param {Node} node The node matched by the pattern. + * @param {goog.dom.TagIterator} position The position where the match + * finished. + * @return {boolean} Returns true to indicate tree changes were made. + */ +goog.dom.pattern.callback.removeNode = function(node, position) { + // Find out which position would be next. + position.setPosition(node, goog.dom.TagWalkType.END_TAG); + + goog.iter.nextOrValue(position, null); + + // Remove the node. + goog.dom.removeNode(node); + + // Correct for the depth change. + position.depth -= 1; + + // Indicate that we made position/tree changes. + return true; +}; + + +/** + * Callback function for use in {@link goog.dom.pattern.Matcher.addPattern} + * that removes the matched node from the tree and replaces it with its + * children. Should be used in conjunction with a + * {@link goog.dom.pattern.StartTag} pattern. + * + * @param {Element} node The node matched by the pattern. + * @param {goog.dom.TagIterator} position The position where the match + * finished. + * @return {boolean} Returns true to indicate tree changes were made. + */ +goog.dom.pattern.callback.flattenElement = function(node, position) { + // Find out which position would be next. + position.setPosition(node, node.firstChild ? + goog.dom.TagWalkType.START_TAG : + goog.dom.TagWalkType.END_TAG); + + goog.iter.nextOrValue(position, null); + + // Flatten the node. + goog.dom.flattenElement(node); + + // Correct for the depth change. + position.depth -= 1; + + // Indicate that we made position/tree changes. + return true; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/callback/counter.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/pattern/callback/counter.js b/externs/GCL/externs/goog/dom/pattern/callback/counter.js new file mode 100644 index 0000000..7e9a7aa --- /dev/null +++ b/externs/GCL/externs/goog/dom/pattern/callback/counter.js @@ -0,0 +1,69 @@ +// Copyright 2007 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview Callback object that counts matches. + * + * @author [email protected] (Robby Walker) + */ + +goog.provide('goog.dom.pattern.callback.Counter'); + + + +/** + * Callback class for counting matches. + * @constructor + * @final + */ +goog.dom.pattern.callback.Counter = function() { + /** + * The count of objects matched so far. + * + * @type {number} + */ + this.count = 0; + + /** + * The callback function. Suitable as a callback for + * {@link goog.dom.pattern.Matcher}. + * @private {Function} + */ + this.callback_ = null; +}; + + +/** + * Get a bound callback function that is suitable as a callback for + * {@link goog.dom.pattern.Matcher}. + * + * @return {!Function} A callback function. + */ +goog.dom.pattern.callback.Counter.prototype.getCallback = function() { + if (!this.callback_) { + this.callback_ = goog.bind(function() { + this.count++; + return false; + }, this); + } + return this.callback_; +}; + + +/** + * Reset the counter. + */ +goog.dom.pattern.callback.Counter.prototype.reset = function() { + this.count = 0; +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/childmatches.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/pattern/childmatches.js b/externs/GCL/externs/goog/dom/pattern/childmatches.js new file mode 100644 index 0000000..72d6674 --- /dev/null +++ b/externs/GCL/externs/goog/dom/pattern/childmatches.js @@ -0,0 +1,145 @@ +// Copyright 2007 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview DOM pattern to match any children of a tag, and + * specifically collect those that match a child pattern. + * + * @author [email protected] (Robby Walker) + */ + +goog.provide('goog.dom.pattern.ChildMatches'); + +goog.require('goog.dom.pattern.AllChildren'); +goog.require('goog.dom.pattern.MatchType'); + + + +/** + * Pattern object that matches any nodes at or below the current tree depth. + * + * @param {goog.dom.pattern.AbstractPattern} childPattern Pattern to collect + * child matches of. + * @param {number=} opt_minimumMatches Enforce a minimum nuber of matches. + * Defaults to 0. + * @constructor + * @extends {goog.dom.pattern.AllChildren} + * @final + */ +goog.dom.pattern.ChildMatches = function(childPattern, opt_minimumMatches) { + /** + * The child pattern to collect matches from. + * + * @private {goog.dom.pattern.AbstractPattern} + */ + this.childPattern_ = childPattern; + + /** + * Array of matched child nodes. + * + * @type {Array<Node>} + */ + this.matches = []; + + /** + * Minimum number of matches. + * + * @private {number} + */ + this.minimumMatches_ = opt_minimumMatches || 0; + + /** + * Whether the pattern has recently matched or failed to match and will need + * to be reset when starting a new round of matches. + * + * @private {boolean} + */ + this.needsReset_ = false; + + goog.dom.pattern.ChildMatches.base(this, 'constructor'); +}; +goog.inherits(goog.dom.pattern.ChildMatches, goog.dom.pattern.AllChildren); + + +/** + * Test whether the given token is on the same level. + * + * @param {Node} token Token to match against. + * @param {goog.dom.TagWalkType} type The type of token. + * @return {goog.dom.pattern.MatchType} {@code MATCHING} if the token is on the + * same level or deeper and {@code BACKTRACK_MATCH} if not. + * @override + */ +goog.dom.pattern.ChildMatches.prototype.matchToken = function(token, type) { + // Defer resets so we maintain our matches array until the last possible time. + if (this.needsReset_) { + this.reset(); + } + + // Call the super-method to ensure we stay in the child tree. + var status = + goog.dom.pattern.AllChildren.prototype.matchToken.apply(this, arguments); + + switch (status) { + case goog.dom.pattern.MatchType.MATCHING: + var backtrack = false; + + switch (this.childPattern_.matchToken(token, type)) { + case goog.dom.pattern.MatchType.BACKTRACK_MATCH: + backtrack = true; + case goog.dom.pattern.MatchType.MATCH: + // Collect the match. + this.matches.push(this.childPattern_.matchedNode); + break; + + default: + // Keep trying if we haven't hit a terminal state. + break; + } + + if (backtrack) { + // The only interesting result is a MATCH, since BACKTRACK_MATCH means + // we are hitting an infinite loop on something like a Repeat(0). + if (this.childPattern_.matchToken(token, type) == + goog.dom.pattern.MatchType.MATCH) { + this.matches.push(this.childPattern_.matchedNode); + } + } + return goog.dom.pattern.MatchType.MATCHING; + + case goog.dom.pattern.MatchType.BACKTRACK_MATCH: + // TODO(robbyw): this should return something like BACKTRACK_NO_MATCH + // when we don't meet our minimum. + this.needsReset_ = true; + return (this.matches.length >= this.minimumMatches_) ? + goog.dom.pattern.MatchType.BACKTRACK_MATCH : + goog.dom.pattern.MatchType.NO_MATCH; + + default: + this.needsReset_ = true; + return status; + } +}; + + +/** + * Reset any internal state this pattern keeps. + * @override + */ +goog.dom.pattern.ChildMatches.prototype.reset = function() { + this.needsReset_ = false; + this.matches.length = 0; + this.childPattern_.reset(); + goog.dom.pattern.AllChildren.prototype.reset.call(this); +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/endtag.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/pattern/endtag.js b/externs/GCL/externs/goog/dom/pattern/endtag.js new file mode 100644 index 0000000..409f952 --- /dev/null +++ b/externs/GCL/externs/goog/dom/pattern/endtag.js @@ -0,0 +1,54 @@ +// Copyright 2007 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview DOM pattern to match the end of a tag. + * + * @author [email protected] (Robby Walker) + */ + +goog.provide('goog.dom.pattern.EndTag'); + +goog.require('goog.dom.TagWalkType'); +goog.require('goog.dom.pattern.Tag'); + + + +/** + * Pattern object that matches a closing tag. + * + * @param {string|RegExp} tag Name of the tag. Also will accept a regular + * expression to match against the tag name. + * @param {Object=} opt_attrs Optional map of attribute names to desired values. + * This pattern will only match when all attributes are present and match + * the string or regular expression value provided here. + * @param {Object=} opt_styles Optional map of CSS style names to desired + * values. This pattern will only match when all styles are present and + * match the string or regular expression value provided here. + * @param {Function=} opt_test Optional function that takes the element as a + * parameter and returns true if this pattern should match it. + * @constructor + * @extends {goog.dom.pattern.Tag} + * @final + */ +goog.dom.pattern.EndTag = function(tag, opt_attrs, opt_styles, opt_test) { + goog.dom.pattern.Tag.call( + this, + tag, + goog.dom.TagWalkType.END_TAG, + opt_attrs, + opt_styles, + opt_test); +}; +goog.inherits(goog.dom.pattern.EndTag, goog.dom.pattern.Tag); http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/fulltag.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/pattern/fulltag.js b/externs/GCL/externs/goog/dom/pattern/fulltag.js new file mode 100644 index 0000000..d12ded1 --- /dev/null +++ b/externs/GCL/externs/goog/dom/pattern/fulltag.js @@ -0,0 +1,88 @@ +// Copyright 2007 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview DOM pattern to match a tag and all of its children. + * + * @author [email protected] (Robby Walker) + */ + +goog.provide('goog.dom.pattern.FullTag'); + +goog.require('goog.dom.pattern.MatchType'); +goog.require('goog.dom.pattern.StartTag'); +goog.require('goog.dom.pattern.Tag'); + + + +/** + * Pattern object that matches a full tag including all its children. + * + * @param {string|RegExp} tag Name of the tag. Also will accept a regular + * expression to match against the tag name. + * @param {Object=} opt_attrs Optional map of attribute names to desired values. + * This pattern will only match when all attributes are present and match + * the string or regular expression value provided here. + * @param {Object=} opt_styles Optional map of CSS style names to desired + * values. This pattern will only match when all styles are present and + * match the string or regular expression value provided here. + * @param {Function=} opt_test Optional function that takes the element as a + * parameter and returns true if this pattern should match it. + * @constructor + * @extends {goog.dom.pattern.StartTag} + * @final + */ +goog.dom.pattern.FullTag = function(tag, opt_attrs, opt_styles, opt_test) { + /** + * Tracks the matcher's depth to detect the end of the tag. + * + * @private {number} + */ + this.depth_ = 0; + + goog.dom.pattern.FullTag.base( + this, 'constructor', tag, opt_attrs, opt_styles, opt_test); +}; +goog.inherits(goog.dom.pattern.FullTag, goog.dom.pattern.StartTag); + + +/** + * Test whether the given token is a start tag token which matches the tag name, + * style, and attributes provided in the constructor. + * + * @param {Node} token Token to match against. + * @param {goog.dom.TagWalkType} type The type of token. + * @return {goog.dom.pattern.MatchType} <code>MATCH</code> at the end of our + * tag, <code>MATCHING</code> if we are within the tag, and + * <code>NO_MATCH</code> if the starting tag does not match. + * @override + */ +goog.dom.pattern.FullTag.prototype.matchToken = function(token, type) { + if (!this.depth_) { + // If we have not yet started, make sure we match as a StartTag. + if (goog.dom.pattern.Tag.prototype.matchToken.call(this, token, type)) { + this.depth_ = type; + return goog.dom.pattern.MatchType.MATCHING; + + } else { + return goog.dom.pattern.MatchType.NO_MATCH; + } + } else { + this.depth_ += type; + + return this.depth_ ? + goog.dom.pattern.MatchType.MATCHING : + goog.dom.pattern.MatchType.MATCH; + } +}; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/matcher.js ---------------------------------------------------------------------- diff --git a/externs/GCL/externs/goog/dom/pattern/matcher.js b/externs/GCL/externs/goog/dom/pattern/matcher.js new file mode 100644 index 0000000..ea4a1e5 --- /dev/null +++ b/externs/GCL/externs/goog/dom/pattern/matcher.js @@ -0,0 +1,144 @@ +// Copyright 2007 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @fileoverview DOM pattern matcher. Allows for simple searching of DOM + * using patterns descended from {@link goog.dom.pattern.AbstractPattern}. + * + * @author [email protected] (Robby Walker) + */ + +goog.provide('goog.dom.pattern.Matcher'); + +goog.require('goog.dom.TagIterator'); +goog.require('goog.dom.pattern.MatchType'); +goog.require('goog.iter'); + + +// TODO(robbyw): Allow for backtracks of size > 1. + + + +/** + * Given a set of patterns and a root node, this class tests the patterns in + * parallel. + * + * It is not (yet) a smart matcher - it doesn't do any advanced backtracking. + * Given the pattern <code>DIV, SPAN</code> the matcher will not match + * <code>DIV, DIV, SPAN</code> because it starts matching at the first + * <code>DIV</code>, fails to match <code>SPAN</code> at the second, and never + * backtracks to try again. + * + * It is also possible to have a set of complex patterns that when matched in + * parallel will miss some possible matches. Running multiple times will catch + * all matches eventually. + * + * @constructor + * @final + */ +goog.dom.pattern.Matcher = function() { + /** + * Array of patterns to attempt to match in parallel. + * + * @private {Array<goog.dom.pattern.AbstractPattern>} + */ + this.patterns_ = []; + + /** + * Array of callbacks to call when a pattern is matched. The indexing is the + * same as the {@link #patterns_} array. + * + * @private {Array<Function>} + */ + this.callbacks_ = []; +}; + + +/** + * Adds a pattern to be matched. The callback can return an object whose keys + * are processing instructions. + * + * @param {goog.dom.pattern.AbstractPattern} pattern The pattern to add. + * @param {Function} callback Function to call when a match is found. Uses + * the above semantics. + */ +goog.dom.pattern.Matcher.prototype.addPattern = function(pattern, callback) { + this.patterns_.push(pattern); + this.callbacks_.push(callback); +}; + + +/** + * Resets all the patterns. + * + * @private + */ +goog.dom.pattern.Matcher.prototype.reset_ = function() { + for (var i = 0, len = this.patterns_.length; i < len; i++) { + this.patterns_[i].reset(); + } +}; + + +/** + * Test the given node against all patterns. + * + * @param {goog.dom.TagIterator} position A position in a node walk that is + * located at the token to process. + * @return {boolean} Whether a pattern modified the position or tree + * and its callback resulted in DOM structure or position modification. + * @private + */ +goog.dom.pattern.Matcher.prototype.matchToken_ = function(position) { + for (var i = 0, len = this.patterns_.length; i < len; i++) { + var pattern = this.patterns_[i]; + switch (pattern.matchToken(position.node, position.tagType)) { + case goog.dom.pattern.MatchType.MATCH: + case goog.dom.pattern.MatchType.BACKTRACK_MATCH: + var callback = this.callbacks_[i]; + + // Callbacks are allowed to modify the current position, but must + // return true if the do. + if (callback(pattern.matchedNode, position, pattern)) { + return true; + } + + default: + // Do nothing. + break; + } + } + + return false; +}; + + +/** + * Match the set of patterns against a match tree. + * + * @param {Node} node The root node of the tree to match. + */ +goog.dom.pattern.Matcher.prototype.match = function(node) { + var position = new goog.dom.TagIterator(node); + + this.reset_(); + + goog.iter.forEach(position, function() { + while (this.matchToken_(position)) { + // Since we've moved, our old pattern statuses don't make sense any more. + // Reset them. + this.reset_(); + } + }, this); +};
