summaryrefslogtreecommitdiffstats
path: root/ecomp-portal-FE/client/bower_components/lodash/vendor
diff options
context:
space:
mode:
Diffstat (limited to 'ecomp-portal-FE/client/bower_components/lodash/vendor')
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/LICENSE22
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/backbone.js1920
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/collection.js1998
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/events.js706
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/model.js1418
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/noconflict.js13
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/router.js1062
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/setup/dom-setup.js4
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/setup/environment.js45
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/sync.js239
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/view.js495
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/license.txt30
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/blank.gifbin43 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/buttonBg.pngbin167 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/buttonBgHover.pngbin171 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/debugger.css331
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/detach.pngbin655 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/detachHover.pngbin586 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disable.gifbin340 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disable.pngbin543 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disableHover.gifbin344 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disableHover.pngbin512 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/down.pngbin637 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/downActive.pngbin543 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/downHover.pngbin526 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/errorIcon-sm.pngbin447 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/errorIcon.gifbin365 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/errorIcon.pngbin457 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug-1.3a2.css817
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.IE6.css20
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.css3147
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.html215
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.pngbin1167 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/group.gifbin158 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/html.css272
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/infoIcon.gifbin359 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/infoIcon.pngbin524 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/loading_16.gifbin1553 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/min.pngbin552 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/minHover.pngbin485 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/off.pngbin742 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/offHover.pngbin680 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/pixel_transparent.gifbin43 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/roundCorner.svg6
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/search.gifbin550 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/search.pngbin685 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/shadow.gifbin4364 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/shadow2.gifbin3093 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/shadowAlpha.pngbin3403 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/sprite.pngbin40027 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabHoverLeft.pngbin438 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabHoverMid.pngbin261 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabHoverRight.pngbin436 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabLeft.pngbin449 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuCheckbox.pngbin220 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuPin.pngbin207 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuRadio.pngbin192 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuTarget.pngbin142 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuTargetHover.pngbin148 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMid.pngbin262 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabRight.pngbin448 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorBorders.gifbin117 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorBorders.pngbin3144 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorCorners.gifbin1821 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorCorners.pngbin3960 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/titlebarMid.pngbin273 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/toolbarMid.pngbin242 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tree_close.gifbin300 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tree_open.gifbin202 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/twistyClosed.pngbin334 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/twistyOpen.pngbin309 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/up.pngbin619 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/upActive.pngbin551 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/upHover.pngbin526 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/warningIcon.gifbin357 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/warningIcon.pngbin516 -> 0 bytes
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/src/firebug-lite-debug.js31176
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/json-js/json2.js519
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/LICENSE23
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/arrays.js555
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/chaining.js99
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/collections.js896
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/cross-document.js141
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/functions.js728
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/objects.js1102
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/utility.js420
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/underscore-min.js6
-rw-r--r--ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/underscore.js1620
88 files changed, 0 insertions, 50045 deletions
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/LICENSE b/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/LICENSE
deleted file mode 100644
index 02c89b26..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2010-2016 Jeremy Ashkenas, DocumentCloud
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/backbone.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/backbone.js
deleted file mode 100644
index 55ccb22b..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/backbone.js
+++ /dev/null
@@ -1,1920 +0,0 @@
-// Backbone.js 1.3.3
-
-// (c) 2010-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
-// Backbone may be freely distributed under the MIT license.
-// For all details and documentation:
-// http://backbonejs.org
-
-(function(factory) {
-
- // Establish the root object, `window` (`self`) in the browser, or `global` on the server.
- // We use `self` instead of `window` for `WebWorker` support.
- var root = (typeof self == 'object' && self.self === self && self) ||
- (typeof global == 'object' && global.global === global && global);
-
- // Set up Backbone appropriately for the environment. Start with AMD.
- if (typeof define === 'function' && define.amd) {
- define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
- // Export global even in AMD case in case this script is loaded with
- // others that may still expect a global Backbone.
- root.Backbone = factory(root, exports, _, $);
- });
-
- // Next for Node.js or CommonJS. jQuery may not be needed as a module.
- } else if (typeof exports !== 'undefined') {
- var _ = require('underscore'), $;
- try { $ = require('jquery'); } catch (e) {}
- factory(root, exports, _, $);
-
- // Finally, as a browser global.
- } else {
- root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
- }
-
-})(function(root, Backbone, _, $) {
-
- // Initial Setup
- // -------------
-
- // Save the previous value of the `Backbone` variable, so that it can be
- // restored later on, if `noConflict` is used.
- var previousBackbone = root.Backbone;
-
- // Create a local reference to a common array method we'll want to use later.
- var slice = Array.prototype.slice;
-
- // Current version of the library. Keep in sync with `package.json`.
- Backbone.VERSION = '1.3.3';
-
- // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
- // the `$` variable.
- Backbone.$ = $;
-
- // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
- // to its previous owner. Returns a reference to this Backbone object.
- Backbone.noConflict = function() {
- root.Backbone = previousBackbone;
- return this;
- };
-
- // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
- // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and
- // set a `X-Http-Method-Override` header.
- Backbone.emulateHTTP = false;
-
- // Turn on `emulateJSON` to support legacy servers that can't deal with direct
- // `application/json` requests ... this will encode the body as
- // `application/x-www-form-urlencoded` instead and will send the model in a
- // form param named `model`.
- Backbone.emulateJSON = false;
-
- // Proxy Backbone class methods to Underscore functions, wrapping the model's
- // `attributes` object or collection's `models` array behind the scenes.
- //
- // collection.filter(function(model) { return model.get('age') > 10 });
- // collection.each(this.addView);
- //
- // `Function#apply` can be slow so we use the method's arg count, if we know it.
- var addMethod = function(length, method, attribute) {
- switch (length) {
- case 1: return function() {
- return _[method](this[attribute]);
- };
- case 2: return function(value) {
- return _[method](this[attribute], value);
- };
- case 3: return function(iteratee, context) {
- return _[method](this[attribute], cb(iteratee, this), context);
- };
- case 4: return function(iteratee, defaultVal, context) {
- return _[method](this[attribute], cb(iteratee, this), defaultVal, context);
- };
- default: return function() {
- var args = slice.call(arguments);
- args.unshift(this[attribute]);
- return _[method].apply(_, args);
- };
- }
- };
- var addUnderscoreMethods = function(Class, methods, attribute) {
- _.each(methods, function(length, method) {
- if (_[method]) Class.prototype[method] = addMethod(length, method, attribute);
- });
- };
-
- // Support `collection.sortBy('attr')` and `collection.findWhere({id: 1})`.
- var cb = function(iteratee, instance) {
- if (_.isFunction(iteratee)) return iteratee;
- if (_.isObject(iteratee) && !instance._isModel(iteratee)) return modelMatcher(iteratee);
- if (_.isString(iteratee)) return function(model) { return model.get(iteratee); };
- return iteratee;
- };
- var modelMatcher = function(attrs) {
- var matcher = _.matches(attrs);
- return function(model) {
- return matcher(model.attributes);
- };
- };
-
- // Backbone.Events
- // ---------------
-
- // A module that can be mixed in to *any object* in order to provide it with
- // a custom event channel. You may bind a callback to an event with `on` or
- // remove with `off`; `trigger`-ing an event fires all callbacks in
- // succession.
- //
- // var object = {};
- // _.extend(object, Backbone.Events);
- // object.on('expand', function(){ alert('expanded'); });
- // object.trigger('expand');
- //
- var Events = Backbone.Events = {};
-
- // Regular expression used to split event strings.
- var eventSplitter = /\s+/;
-
- // Iterates over the standard `event, callback` (as well as the fancy multiple
- // space-separated events `"change blur", callback` and jQuery-style event
- // maps `{event: callback}`).
- var eventsApi = function(iteratee, events, name, callback, opts) {
- var i = 0, names;
- if (name && typeof name === 'object') {
- // Handle event maps.
- if (callback !== void 0 && 'context' in opts && opts.context === void 0) opts.context = callback;
- for (names = _.keys(name); i < names.length ; i++) {
- events = eventsApi(iteratee, events, names[i], name[names[i]], opts);
- }
- } else if (name && eventSplitter.test(name)) {
- // Handle space-separated event names by delegating them individually.
- for (names = name.split(eventSplitter); i < names.length; i++) {
- events = iteratee(events, names[i], callback, opts);
- }
- } else {
- // Finally, standard events.
- events = iteratee(events, name, callback, opts);
- }
- return events;
- };
-
- // Bind an event to a `callback` function. Passing `"all"` will bind
- // the callback to all events fired.
- Events.on = function(name, callback, context) {
- return internalOn(this, name, callback, context);
- };
-
- // Guard the `listening` argument from the public API.
- var internalOn = function(obj, name, callback, context, listening) {
- obj._events = eventsApi(onApi, obj._events || {}, name, callback, {
- context: context,
- ctx: obj,
- listening: listening
- });
-
- if (listening) {
- var listeners = obj._listeners || (obj._listeners = {});
- listeners[listening.id] = listening;
- }
-
- return obj;
- };
-
- // Inversion-of-control versions of `on`. Tell *this* object to listen to
- // an event in another object... keeping track of what it's listening to
- // for easier unbinding later.
- Events.listenTo = function(obj, name, callback) {
- if (!obj) return this;
- var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
- var listeningTo = this._listeningTo || (this._listeningTo = {});
- var listening = listeningTo[id];
-
- // This object is not listening to any other events on `obj` yet.
- // Setup the necessary references to track the listening callbacks.
- if (!listening) {
- var thisId = this._listenId || (this._listenId = _.uniqueId('l'));
- listening = listeningTo[id] = {obj: obj, objId: id, id: thisId, listeningTo: listeningTo, count: 0};
- }
-
- // Bind callbacks on obj, and keep track of them on listening.
- internalOn(obj, name, callback, this, listening);
- return this;
- };
-
- // The reducing API that adds a callback to the `events` object.
- var onApi = function(events, name, callback, options) {
- if (callback) {
- var handlers = events[name] || (events[name] = []);
- var context = options.context, ctx = options.ctx, listening = options.listening;
- if (listening) listening.count++;
-
- handlers.push({callback: callback, context: context, ctx: context || ctx, listening: listening});
- }
- return events;
- };
-
- // Remove one or many callbacks. If `context` is null, removes all
- // callbacks with that function. If `callback` is null, removes all
- // callbacks for the event. If `name` is null, removes all bound
- // callbacks for all events.
- Events.off = function(name, callback, context) {
- if (!this._events) return this;
- this._events = eventsApi(offApi, this._events, name, callback, {
- context: context,
- listeners: this._listeners
- });
- return this;
- };
-
- // Tell this object to stop listening to either specific events ... or
- // to every object it's currently listening to.
- Events.stopListening = function(obj, name, callback) {
- var listeningTo = this._listeningTo;
- if (!listeningTo) return this;
-
- var ids = obj ? [obj._listenId] : _.keys(listeningTo);
-
- for (var i = 0; i < ids.length; i++) {
- var listening = listeningTo[ids[i]];
-
- // If listening doesn't exist, this object is not currently
- // listening to obj. Break out early.
- if (!listening) break;
-
- listening.obj.off(name, callback, this);
- }
-
- return this;
- };
-
- // The reducing API that removes a callback from the `events` object.
- var offApi = function(events, name, callback, options) {
- if (!events) return;
-
- var i = 0, listening;
- var context = options.context, listeners = options.listeners;
-
- // Delete all events listeners and "drop" events.
- if (!name && !callback && !context) {
- var ids = _.keys(listeners);
- for (; i < ids.length; i++) {
- listening = listeners[ids[i]];
- delete listeners[listening.id];
- delete listening.listeningTo[listening.objId];
- }
- return;
- }
-
- var names = name ? [name] : _.keys(events);
- for (; i < names.length; i++) {
- name = names[i];
- var handlers = events[name];
-
- // Bail out if there are no events stored.
- if (!handlers) break;
-
- // Replace events if there are any remaining. Otherwise, clean up.
- var remaining = [];
- for (var j = 0; j < handlers.length; j++) {
- var handler = handlers[j];
- if (
- callback && callback !== handler.callback &&
- callback !== handler.callback._callback ||
- context && context !== handler.context
- ) {
- remaining.push(handler);
- } else {
- listening = handler.listening;
- if (listening && --listening.count === 0) {
- delete listeners[listening.id];
- delete listening.listeningTo[listening.objId];
- }
- }
- }
-
- // Update tail event if the list has any events. Otherwise, clean up.
- if (remaining.length) {
- events[name] = remaining;
- } else {
- delete events[name];
- }
- }
- return events;
- };
-
- // Bind an event to only be triggered a single time. After the first time
- // the callback is invoked, its listener will be removed. If multiple events
- // are passed in using the space-separated syntax, the handler will fire
- // once for each event, not once for a combination of all events.
- Events.once = function(name, callback, context) {
- // Map the event into a `{event: once}` object.
- var events = eventsApi(onceMap, {}, name, callback, _.bind(this.off, this));
- if (typeof name === 'string' && context == null) callback = void 0;
- return this.on(events, callback, context);
- };
-
- // Inversion-of-control versions of `once`.
- Events.listenToOnce = function(obj, name, callback) {
- // Map the event into a `{event: once}` object.
- var events = eventsApi(onceMap, {}, name, callback, _.bind(this.stopListening, this, obj));
- return this.listenTo(obj, events);
- };
-
- // Reduces the event callbacks into a map of `{event: onceWrapper}`.
- // `offer` unbinds the `onceWrapper` after it has been called.
- var onceMap = function(map, name, callback, offer) {
- if (callback) {
- var once = map[name] = _.once(function() {
- offer(name, once);
- callback.apply(this, arguments);
- });
- once._callback = callback;
- }
- return map;
- };
-
- // Trigger one or many events, firing all bound callbacks. Callbacks are
- // passed the same arguments as `trigger` is, apart from the event name
- // (unless you're listening on `"all"`, which will cause your callback to
- // receive the true name of the event as the first argument).
- Events.trigger = function(name) {
- if (!this._events) return this;
-
- var length = Math.max(0, arguments.length - 1);
- var args = Array(length);
- for (var i = 0; i < length; i++) args[i] = arguments[i + 1];
-
- eventsApi(triggerApi, this._events, name, void 0, args);
- return this;
- };
-
- // Handles triggering the appropriate event callbacks.
- var triggerApi = function(objEvents, name, callback, args) {
- if (objEvents) {
- var events = objEvents[name];
- var allEvents = objEvents.all;
- if (events && allEvents) allEvents = allEvents.slice();
- if (events) triggerEvents(events, args);
- if (allEvents) triggerEvents(allEvents, [name].concat(args));
- }
- return objEvents;
- };
-
- // A difficult-to-believe, but optimized internal dispatch function for
- // triggering events. Tries to keep the usual cases speedy (most internal
- // Backbone events have 3 arguments).
- var triggerEvents = function(events, args) {
- var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
- switch (args.length) {
- case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
- case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
- case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
- case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
- default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
- }
- };
-
- // Aliases for backwards compatibility.
- Events.bind = Events.on;
- Events.unbind = Events.off;
-
- // Allow the `Backbone` object to serve as a global event bus, for folks who
- // want global "pubsub" in a convenient place.
- _.extend(Backbone, Events);
-
- // Backbone.Model
- // --------------
-
- // Backbone **Models** are the basic data object in the framework --
- // frequently representing a row in a table in a database on your server.
- // A discrete chunk of data and a bunch of useful, related methods for
- // performing computations and transformations on that data.
-
- // Create a new model with the specified attributes. A client id (`cid`)
- // is automatically generated and assigned for you.
- var Model = Backbone.Model = function(attributes, options) {
- var attrs = attributes || {};
- options || (options = {});
- this.cid = _.uniqueId(this.cidPrefix);
- this.attributes = {};
- if (options.collection) this.collection = options.collection;
- if (options.parse) attrs = this.parse(attrs, options) || {};
- var defaults = _.result(this, 'defaults');
- attrs = _.defaults(_.extend({}, defaults, attrs), defaults);
- this.set(attrs, options);
- this.changed = {};
- this.initialize.apply(this, arguments);
- };
-
- // Attach all inheritable methods to the Model prototype.
- _.extend(Model.prototype, Events, {
-
- // A hash of attributes whose current and previous value differ.
- changed: null,
-
- // The value returned during the last failed validation.
- validationError: null,
-
- // The default name for the JSON `id` attribute is `"id"`. MongoDB and
- // CouchDB users may want to set this to `"_id"`.
- idAttribute: 'id',
-
- // The prefix is used to create the client id which is used to identify models locally.
- // You may want to override this if you're experiencing name clashes with model ids.
- cidPrefix: 'c',
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // Return a copy of the model's `attributes` object.
- toJSON: function(options) {
- return _.clone(this.attributes);
- },
-
- // Proxy `Backbone.sync` by default -- but override this if you need
- // custom syncing semantics for *this* particular model.
- sync: function() {
- return Backbone.sync.apply(this, arguments);
- },
-
- // Get the value of an attribute.
- get: function(attr) {
- return this.attributes[attr];
- },
-
- // Get the HTML-escaped value of an attribute.
- escape: function(attr) {
- return _.escape(this.get(attr));
- },
-
- // Returns `true` if the attribute contains a value that is not null
- // or undefined.
- has: function(attr) {
- return this.get(attr) != null;
- },
-
- // Special-cased proxy to underscore's `_.matches` method.
- matches: function(attrs) {
- return !!_.iteratee(attrs, this)(this.attributes);
- },
-
- // Set a hash of model attributes on the object, firing `"change"`. This is
- // the core primitive operation of a model, updating the data and notifying
- // anyone who needs to know about the change in state. The heart of the beast.
- set: function(key, val, options) {
- if (key == null) return this;
-
- // Handle both `"key", value` and `{key: value}` -style arguments.
- var attrs;
- if (typeof key === 'object') {
- attrs = key;
- options = val;
- } else {
- (attrs = {})[key] = val;
- }
-
- options || (options = {});
-
- // Run validation.
- if (!this._validate(attrs, options)) return false;
-
- // Extract attributes and options.
- var unset = options.unset;
- var silent = options.silent;
- var changes = [];
- var changing = this._changing;
- this._changing = true;
-
- if (!changing) {
- this._previousAttributes = _.clone(this.attributes);
- this.changed = {};
- }
-
- var current = this.attributes;
- var changed = this.changed;
- var prev = this._previousAttributes;
-
- // For each `set` attribute, update or delete the current value.
- for (var attr in attrs) {
- val = attrs[attr];
- if (!_.isEqual(current[attr], val)) changes.push(attr);
- if (!_.isEqual(prev[attr], val)) {
- changed[attr] = val;
- } else {
- delete changed[attr];
- }
- unset ? delete current[attr] : current[attr] = val;
- }
-
- // Update the `id`.
- if (this.idAttribute in attrs) this.id = this.get(this.idAttribute);
-
- // Trigger all relevant attribute changes.
- if (!silent) {
- if (changes.length) this._pending = options;
- for (var i = 0; i < changes.length; i++) {
- this.trigger('change:' + changes[i], this, current[changes[i]], options);
- }
- }
-
- // You might be wondering why there's a `while` loop here. Changes can
- // be recursively nested within `"change"` events.
- if (changing) return this;
- if (!silent) {
- while (this._pending) {
- options = this._pending;
- this._pending = false;
- this.trigger('change', this, options);
- }
- }
- this._pending = false;
- this._changing = false;
- return this;
- },
-
- // Remove an attribute from the model, firing `"change"`. `unset` is a noop
- // if the attribute doesn't exist.
- unset: function(attr, options) {
- return this.set(attr, void 0, _.extend({}, options, {unset: true}));
- },
-
- // Clear all attributes on the model, firing `"change"`.
- clear: function(options) {
- var attrs = {};
- for (var key in this.attributes) attrs[key] = void 0;
- return this.set(attrs, _.extend({}, options, {unset: true}));
- },
-
- // Determine if the model has changed since the last `"change"` event.
- // If you specify an attribute name, determine if that attribute has changed.
- hasChanged: function(attr) {
- if (attr == null) return !_.isEmpty(this.changed);
- return _.has(this.changed, attr);
- },
-
- // Return an object containing all the attributes that have changed, or
- // false if there are no changed attributes. Useful for determining what
- // parts of a view need to be updated and/or what attributes need to be
- // persisted to the server. Unset attributes will be set to undefined.
- // You can also pass an attributes object to diff against the model,
- // determining if there *would be* a change.
- changedAttributes: function(diff) {
- if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
- var old = this._changing ? this._previousAttributes : this.attributes;
- var changed = {};
- for (var attr in diff) {
- var val = diff[attr];
- if (_.isEqual(old[attr], val)) continue;
- changed[attr] = val;
- }
- return _.size(changed) ? changed : false;
- },
-
- // Get the previous value of an attribute, recorded at the time the last
- // `"change"` event was fired.
- previous: function(attr) {
- if (attr == null || !this._previousAttributes) return null;
- return this._previousAttributes[attr];
- },
-
- // Get all of the attributes of the model at the time of the previous
- // `"change"` event.
- previousAttributes: function() {
- return _.clone(this._previousAttributes);
- },
-
- // Fetch the model from the server, merging the response with the model's
- // local attributes. Any changed attributes will trigger a "change" event.
- fetch: function(options) {
- options = _.extend({parse: true}, options);
- var model = this;
- var success = options.success;
- options.success = function(resp) {
- var serverAttrs = options.parse ? model.parse(resp, options) : resp;
- if (!model.set(serverAttrs, options)) return false;
- if (success) success.call(options.context, model, resp, options);
- model.trigger('sync', model, resp, options);
- };
- wrapError(this, options);
- return this.sync('read', this, options);
- },
-
- // Set a hash of model attributes, and sync the model to the server.
- // If the server returns an attributes hash that differs, the model's
- // state will be `set` again.
- save: function(key, val, options) {
- // Handle both `"key", value` and `{key: value}` -style arguments.
- var attrs;
- if (key == null || typeof key === 'object') {
- attrs = key;
- options = val;
- } else {
- (attrs = {})[key] = val;
- }
-
- options = _.extend({validate: true, parse: true}, options);
- var wait = options.wait;
-
- // If we're not waiting and attributes exist, save acts as
- // `set(attr).save(null, opts)` with validation. Otherwise, check if
- // the model will be valid when the attributes, if any, are set.
- if (attrs && !wait) {
- if (!this.set(attrs, options)) return false;
- } else if (!this._validate(attrs, options)) {
- return false;
- }
-
- // After a successful server-side save, the client is (optionally)
- // updated with the server-side state.
- var model = this;
- var success = options.success;
- var attributes = this.attributes;
- options.success = function(resp) {
- // Ensure attributes are restored during synchronous saves.
- model.attributes = attributes;
- var serverAttrs = options.parse ? model.parse(resp, options) : resp;
- if (wait) serverAttrs = _.extend({}, attrs, serverAttrs);
- if (serverAttrs && !model.set(serverAttrs, options)) return false;
- if (success) success.call(options.context, model, resp, options);
- model.trigger('sync', model, resp, options);
- };
- wrapError(this, options);
-
- // Set temporary attributes if `{wait: true}` to properly find new ids.
- if (attrs && wait) this.attributes = _.extend({}, attributes, attrs);
-
- var method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
- if (method === 'patch' && !options.attrs) options.attrs = attrs;
- var xhr = this.sync(method, this, options);
-
- // Restore attributes.
- this.attributes = attributes;
-
- return xhr;
- },
-
- // Destroy this model on the server if it was already persisted.
- // Optimistically removes the model from its collection, if it has one.
- // If `wait: true` is passed, waits for the server to respond before removal.
- destroy: function(options) {
- options = options ? _.clone(options) : {};
- var model = this;
- var success = options.success;
- var wait = options.wait;
-
- var destroy = function() {
- model.stopListening();
- model.trigger('destroy', model, model.collection, options);
- };
-
- options.success = function(resp) {
- if (wait) destroy();
- if (success) success.call(options.context, model, resp, options);
- if (!model.isNew()) model.trigger('sync', model, resp, options);
- };
-
- var xhr = false;
- if (this.isNew()) {
- _.defer(options.success);
- } else {
- wrapError(this, options);
- xhr = this.sync('delete', this, options);
- }
- if (!wait) destroy();
- return xhr;
- },
-
- // Default URL for the model's representation on the server -- if you're
- // using Backbone's restful methods, override this to change the endpoint
- // that will be called.
- url: function() {
- var base =
- _.result(this, 'urlRoot') ||
- _.result(this.collection, 'url') ||
- urlError();
- if (this.isNew()) return base;
- var id = this.get(this.idAttribute);
- return base.replace(/[^\/]$/, '$&/') + encodeURIComponent(id);
- },
-
- // **parse** converts a response into the hash of attributes to be `set` on
- // the model. The default implementation is just to pass the response along.
- parse: function(resp, options) {
- return resp;
- },
-
- // Create a new model with identical attributes to this one.
- clone: function() {
- return new this.constructor(this.attributes);
- },
-
- // A model is new if it has never been saved to the server, and lacks an id.
- isNew: function() {
- return !this.has(this.idAttribute);
- },
-
- // Check if the model is currently in a valid state.
- isValid: function(options) {
- return this._validate({}, _.extend({}, options, {validate: true}));
- },
-
- // Run validation against the next complete set of model attributes,
- // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
- _validate: function(attrs, options) {
- if (!options.validate || !this.validate) return true;
- attrs = _.extend({}, this.attributes, attrs);
- var error = this.validationError = this.validate(attrs, options) || null;
- if (!error) return true;
- this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
- return false;
- }
-
- });
-
- // Underscore methods that we want to implement on the Model, mapped to the
- // number of arguments they take.
- var modelMethods = {keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
- omit: 0, chain: 1, isEmpty: 1};
-
- // Mix in each Underscore method as a proxy to `Model#attributes`.
- addUnderscoreMethods(Model, modelMethods, 'attributes');
-
- // Backbone.Collection
- // -------------------
-
- // If models tend to represent a single row of data, a Backbone Collection is
- // more analogous to a table full of data ... or a small slice or page of that
- // table, or a collection of rows that belong together for a particular reason
- // -- all of the messages in this particular folder, all of the documents
- // belonging to this particular author, and so on. Collections maintain
- // indexes of their models, both in order, and for lookup by `id`.
-
- // Create a new **Collection**, perhaps to contain a specific type of `model`.
- // If a `comparator` is specified, the Collection will maintain
- // its models in sort order, as they're added and removed.
- var Collection = Backbone.Collection = function(models, options) {
- options || (options = {});
- if (options.model) this.model = options.model;
- if (options.comparator !== void 0) this.comparator = options.comparator;
- this._reset();
- this.initialize.apply(this, arguments);
- if (models) this.reset(models, _.extend({silent: true}, options));
- };
-
- // Default options for `Collection#set`.
- var setOptions = {add: true, remove: true, merge: true};
- var addOptions = {add: true, remove: false};
-
- // Splices `insert` into `array` at index `at`.
- var splice = function(array, insert, at) {
- at = Math.min(Math.max(at, 0), array.length);
- var tail = Array(array.length - at);
- var length = insert.length;
- var i;
- for (i = 0; i < tail.length; i++) tail[i] = array[i + at];
- for (i = 0; i < length; i++) array[i + at] = insert[i];
- for (i = 0; i < tail.length; i++) array[i + length + at] = tail[i];
- };
-
- // Define the Collection's inheritable methods.
- _.extend(Collection.prototype, Events, {
-
- // The default model for a collection is just a **Backbone.Model**.
- // This should be overridden in most cases.
- model: Model,
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // The JSON representation of a Collection is an array of the
- // models' attributes.
- toJSON: function(options) {
- return this.map(function(model) { return model.toJSON(options); });
- },
-
- // Proxy `Backbone.sync` by default.
- sync: function() {
- return Backbone.sync.apply(this, arguments);
- },
-
- // Add a model, or list of models to the set. `models` may be Backbone
- // Models or raw JavaScript objects to be converted to Models, or any
- // combination of the two.
- add: function(models, options) {
- return this.set(models, _.extend({merge: false}, options, addOptions));
- },
-
- // Remove a model, or a list of models from the set.
- remove: function(models, options) {
- options = _.extend({}, options);
- var singular = !_.isArray(models);
- models = singular ? [models] : models.slice();
- var removed = this._removeModels(models, options);
- if (!options.silent && removed.length) {
- options.changes = {added: [], merged: [], removed: removed};
- this.trigger('update', this, options);
- }
- return singular ? removed[0] : removed;
- },
-
- // Update a collection by `set`-ing a new list of models, adding new ones,
- // removing models that are no longer present, and merging models that
- // already exist in the collection, as necessary. Similar to **Model#set**,
- // the core operation for updating the data contained by the collection.
- set: function(models, options) {
- if (models == null) return;
-
- options = _.extend({}, setOptions, options);
- if (options.parse && !this._isModel(models)) {
- models = this.parse(models, options) || [];
- }
-
- var singular = !_.isArray(models);
- models = singular ? [models] : models.slice();
-
- var at = options.at;
- if (at != null) at = +at;
- if (at > this.length) at = this.length;
- if (at < 0) at += this.length + 1;
-
- var set = [];
- var toAdd = [];
- var toMerge = [];
- var toRemove = [];
- var modelMap = {};
-
- var add = options.add;
- var merge = options.merge;
- var remove = options.remove;
-
- var sort = false;
- var sortable = this.comparator && at == null && options.sort !== false;
- var sortAttr = _.isString(this.comparator) ? this.comparator : null;
-
- // Turn bare objects into model references, and prevent invalid models
- // from being added.
- var model, i;
- for (i = 0; i < models.length; i++) {
- model = models[i];
-
- // If a duplicate is found, prevent it from being added and
- // optionally merge it into the existing model.
- var existing = this.get(model);
- if (existing) {
- if (merge && model !== existing) {
- var attrs = this._isModel(model) ? model.attributes : model;
- if (options.parse) attrs = existing.parse(attrs, options);
- existing.set(attrs, options);
- toMerge.push(existing);
- if (sortable && !sort) sort = existing.hasChanged(sortAttr);
- }
- if (!modelMap[existing.cid]) {
- modelMap[existing.cid] = true;
- set.push(existing);
- }
- models[i] = existing;
-
- // If this is a new, valid model, push it to the `toAdd` list.
- } else if (add) {
- model = models[i] = this._prepareModel(model, options);
- if (model) {
- toAdd.push(model);
- this._addReference(model, options);
- modelMap[model.cid] = true;
- set.push(model);
- }
- }
- }
-
- // Remove stale models.
- if (remove) {
- for (i = 0; i < this.length; i++) {
- model = this.models[i];
- if (!modelMap[model.cid]) toRemove.push(model);
- }
- if (toRemove.length) this._removeModels(toRemove, options);
- }
-
- // See if sorting is needed, update `length` and splice in new models.
- var orderChanged = false;
- var replace = !sortable && add && remove;
- if (set.length && replace) {
- orderChanged = this.length !== set.length || _.some(this.models, function(m, index) {
- return m !== set[index];
- });
- this.models.length = 0;
- splice(this.models, set, 0);
- this.length = this.models.length;
- } else if (toAdd.length) {
- if (sortable) sort = true;
- splice(this.models, toAdd, at == null ? this.length : at);
- this.length = this.models.length;
- }
-
- // Silently sort the collection if appropriate.
- if (sort) this.sort({silent: true});
-
- // Unless silenced, it's time to fire all appropriate add/sort/update events.
- if (!options.silent) {
- for (i = 0; i < toAdd.length; i++) {
- if (at != null) options.index = at + i;
- model = toAdd[i];
- model.trigger('add', model, this, options);
- }
- if (sort || orderChanged) this.trigger('sort', this, options);
- if (toAdd.length || toRemove.length || toMerge.length) {
- options.changes = {
- added: toAdd,
- removed: toRemove,
- merged: toMerge
- };
- this.trigger('update', this, options);
- }
- }
-
- // Return the added (or merged) model (or models).
- return singular ? models[0] : models;
- },
-
- // When you have more items than you want to add or remove individually,
- // you can reset the entire set with a new list of models, without firing
- // any granular `add` or `remove` events. Fires `reset` when finished.
- // Useful for bulk operations and optimizations.
- reset: function(models, options) {
- options = options ? _.clone(options) : {};
- for (var i = 0; i < this.models.length; i++) {
- this._removeReference(this.models[i], options);
- }
- options.previousModels = this.models;
- this._reset();
- models = this.add(models, _.extend({silent: true}, options));
- if (!options.silent) this.trigger('reset', this, options);
- return models;
- },
-
- // Add a model to the end of the collection.
- push: function(model, options) {
- return this.add(model, _.extend({at: this.length}, options));
- },
-
- // Remove a model from the end of the collection.
- pop: function(options) {
- var model = this.at(this.length - 1);
- return this.remove(model, options);
- },
-
- // Add a model to the beginning of the collection.
- unshift: function(model, options) {
- return this.add(model, _.extend({at: 0}, options));
- },
-
- // Remove a model from the beginning of the collection.
- shift: function(options) {
- var model = this.at(0);
- return this.remove(model, options);
- },
-
- // Slice out a sub-array of models from the collection.
- slice: function() {
- return slice.apply(this.models, arguments);
- },
-
- // Get a model from the set by id, cid, model object with id or cid
- // properties, or an attributes object that is transformed through modelId.
- get: function(obj) {
- if (obj == null) return void 0;
- return this._byId[obj] ||
- this._byId[this.modelId(obj.attributes || obj)] ||
- obj.cid && this._byId[obj.cid];
- },
-
- // Returns `true` if the model is in the collection.
- has: function(obj) {
- return this.get(obj) != null;
- },
-
- // Get the model at the given index.
- at: function(index) {
- if (index < 0) index += this.length;
- return this.models[index];
- },
-
- // Return models with matching attributes. Useful for simple cases of
- // `filter`.
- where: function(attrs, first) {
- return this[first ? 'find' : 'filter'](attrs);
- },
-
- // Return the first model with matching attributes. Useful for simple cases
- // of `find`.
- findWhere: function(attrs) {
- return this.where(attrs, true);
- },
-
- // Force the collection to re-sort itself. You don't need to call this under
- // normal circumstances, as the set will maintain sort order as each item
- // is added.
- sort: function(options) {
- var comparator = this.comparator;
- if (!comparator) throw new Error('Cannot sort a set without a comparator');
- options || (options = {});
-
- var length = comparator.length;
- if (_.isFunction(comparator)) comparator = _.bind(comparator, this);
-
- // Run sort based on type of `comparator`.
- if (length === 1 || _.isString(comparator)) {
- this.models = this.sortBy(comparator);
- } else {
- this.models.sort(comparator);
- }
- if (!options.silent) this.trigger('sort', this, options);
- return this;
- },
-
- // Pluck an attribute from each model in the collection.
- pluck: function(attr) {
- return this.map(attr + '');
- },
-
- // Fetch the default set of models for this collection, resetting the
- // collection when they arrive. If `reset: true` is passed, the response
- // data will be passed through the `reset` method instead of `set`.
- fetch: function(options) {
- options = _.extend({parse: true}, options);
- var success = options.success;
- var collection = this;
- options.success = function(resp) {
- var method = options.reset ? 'reset' : 'set';
- collection[method](resp, options);
- if (success) success.call(options.context, collection, resp, options);
- collection.trigger('sync', collection, resp, options);
- };
- wrapError(this, options);
- return this.sync('read', this, options);
- },
-
- // Create a new instance of a model in this collection. Add the model to the
- // collection immediately, unless `wait: true` is passed, in which case we
- // wait for the server to agree.
- create: function(model, options) {
- options = options ? _.clone(options) : {};
- var wait = options.wait;
- model = this._prepareModel(model, options);
- if (!model) return false;
- if (!wait) this.add(model, options);
- var collection = this;
- var success = options.success;
- options.success = function(m, resp, callbackOpts) {
- if (wait) collection.add(m, callbackOpts);
- if (success) success.call(callbackOpts.context, m, resp, callbackOpts);
- };
- model.save(null, options);
- return model;
- },
-
- // **parse** converts a response into a list of models to be added to the
- // collection. The default implementation is just to pass it through.
- parse: function(resp, options) {
- return resp;
- },
-
- // Create a new collection with an identical list of models as this one.
- clone: function() {
- return new this.constructor(this.models, {
- model: this.model,
- comparator: this.comparator
- });
- },
-
- // Define how to uniquely identify models in the collection.
- modelId: function(attrs) {
- return attrs[this.model.prototype.idAttribute || 'id'];
- },
-
- // Private method to reset all internal state. Called when the collection
- // is first initialized or reset.
- _reset: function() {
- this.length = 0;
- this.models = [];
- this._byId = {};
- },
-
- // Prepare a hash of attributes (or other model) to be added to this
- // collection.
- _prepareModel: function(attrs, options) {
- if (this._isModel(attrs)) {
- if (!attrs.collection) attrs.collection = this;
- return attrs;
- }
- options = options ? _.clone(options) : {};
- options.collection = this;
- var model = new this.model(attrs, options);
- if (!model.validationError) return model;
- this.trigger('invalid', this, model.validationError, options);
- return false;
- },
-
- // Internal method called by both remove and set.
- _removeModels: function(models, options) {
- var removed = [];
- for (var i = 0; i < models.length; i++) {
- var model = this.get(models[i]);
- if (!model) continue;
-
- var index = this.indexOf(model);
- this.models.splice(index, 1);
- this.length--;
-
- // Remove references before triggering 'remove' event to prevent an
- // infinite loop. #3693
- delete this._byId[model.cid];
- var id = this.modelId(model.attributes);
- if (id != null) delete this._byId[id];
-
- if (!options.silent) {
- options.index = index;
- model.trigger('remove', model, this, options);
- }
-
- removed.push(model);
- this._removeReference(model, options);
- }
- return removed;
- },
-
- // Method for checking whether an object should be considered a model for
- // the purposes of adding to the collection.
- _isModel: function(model) {
- return model instanceof Model;
- },
-
- // Internal method to create a model's ties to a collection.
- _addReference: function(model, options) {
- this._byId[model.cid] = model;
- var id = this.modelId(model.attributes);
- if (id != null) this._byId[id] = model;
- model.on('all', this._onModelEvent, this);
- },
-
- // Internal method to sever a model's ties to a collection.
- _removeReference: function(model, options) {
- delete this._byId[model.cid];
- var id = this.modelId(model.attributes);
- if (id != null) delete this._byId[id];
- if (this === model.collection) delete model.collection;
- model.off('all', this._onModelEvent, this);
- },
-
- // Internal method called every time a model in the set fires an event.
- // Sets need to update their indexes when models change ids. All other
- // events simply proxy through. "add" and "remove" events that originate
- // in other collections are ignored.
- _onModelEvent: function(event, model, collection, options) {
- if (model) {
- if ((event === 'add' || event === 'remove') && collection !== this) return;
- if (event === 'destroy') this.remove(model, options);
- if (event === 'change') {
- var prevId = this.modelId(model.previousAttributes());
- var id = this.modelId(model.attributes);
- if (prevId !== id) {
- if (prevId != null) delete this._byId[prevId];
- if (id != null) this._byId[id] = model;
- }
- }
- }
- this.trigger.apply(this, arguments);
- }
-
- });
-
- // Underscore methods that we want to implement on the Collection.
- // 90% of the core usefulness of Backbone Collections is actually implemented
- // right here:
- var collectionMethods = {forEach: 3, each: 3, map: 3, collect: 3, reduce: 0,
- foldl: 0, inject: 0, reduceRight: 0, foldr: 0, find: 3, detect: 3, filter: 3,
- select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 3, includes: 3,
- contains: 3, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3,
- head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3,
- without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3,
- isEmpty: 1, chain: 1, sample: 3, partition: 3, groupBy: 3, countBy: 3,
- sortBy: 3, indexBy: 3, findIndex: 3, findLastIndex: 3};
-
- // Mix in each Underscore method as a proxy to `Collection#models`.
- addUnderscoreMethods(Collection, collectionMethods, 'models');
-
- // Backbone.View
- // -------------
-
- // Backbone Views are almost more convention than they are actual code. A View
- // is simply a JavaScript object that represents a logical chunk of UI in the
- // DOM. This might be a single item, an entire list, a sidebar or panel, or
- // even the surrounding frame which wraps your whole app. Defining a chunk of
- // UI as a **View** allows you to define your DOM events declaratively, without
- // having to worry about render order ... and makes it easy for the view to
- // react to specific changes in the state of your models.
-
- // Creating a Backbone.View creates its initial element outside of the DOM,
- // if an existing element is not provided...
- var View = Backbone.View = function(options) {
- this.cid = _.uniqueId('view');
- _.extend(this, _.pick(options, viewOptions));
- this._ensureElement();
- this.initialize.apply(this, arguments);
- };
-
- // Cached regex to split keys for `delegate`.
- var delegateEventSplitter = /^(\S+)\s*(.*)$/;
-
- // List of view options to be set as properties.
- var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
-
- // Set up all inheritable **Backbone.View** properties and methods.
- _.extend(View.prototype, Events, {
-
- // The default `tagName` of a View's element is `"div"`.
- tagName: 'div',
-
- // jQuery delegate for element lookup, scoped to DOM elements within the
- // current view. This should be preferred to global lookups where possible.
- $: function(selector) {
- return this.$el.find(selector);
- },
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // **render** is the core function that your view should override, in order
- // to populate its element (`this.el`), with the appropriate HTML. The
- // convention is for **render** to always return `this`.
- render: function() {
- return this;
- },
-
- // Remove this view by taking the element out of the DOM, and removing any
- // applicable Backbone.Events listeners.
- remove: function() {
- this._removeElement();
- this.stopListening();
- return this;
- },
-
- // Remove this view's element from the document and all event listeners
- // attached to it. Exposed for subclasses using an alternative DOM
- // manipulation API.
- _removeElement: function() {
- this.$el.remove();
- },
-
- // Change the view's element (`this.el` property) and re-delegate the
- // view's events on the new element.
- setElement: function(element) {
- this.undelegateEvents();
- this._setElement(element);
- this.delegateEvents();
- return this;
- },
-
- // Creates the `this.el` and `this.$el` references for this view using the
- // given `el`. `el` can be a CSS selector or an HTML string, a jQuery
- // context or an element. Subclasses can override this to utilize an
- // alternative DOM manipulation API and are only required to set the
- // `this.el` property.
- _setElement: function(el) {
- this.$el = el instanceof Backbone.$ ? el : Backbone.$(el);
- this.el = this.$el[0];
- },
-
- // Set callbacks, where `this.events` is a hash of
- //
- // *{"event selector": "callback"}*
- //
- // {
- // 'mousedown .title': 'edit',
- // 'click .button': 'save',
- // 'click .open': function(e) { ... }
- // }
- //
- // pairs. Callbacks will be bound to the view, with `this` set properly.
- // Uses event delegation for efficiency.
- // Omitting the selector binds the event to `this.el`.
- delegateEvents: function(events) {
- events || (events = _.result(this, 'events'));
- if (!events) return this;
- this.undelegateEvents();
- for (var key in events) {
- var method = events[key];
- if (!_.isFunction(method)) method = this[method];
- if (!method) continue;
- var match = key.match(delegateEventSplitter);
- this.delegate(match[1], match[2], _.bind(method, this));
- }
- return this;
- },
-
- // Add a single event listener to the view's element (or a child element
- // using `selector`). This only works for delegate-able events: not `focus`,
- // `blur`, and not `change`, `submit`, and `reset` in Internet Explorer.
- delegate: function(eventName, selector, listener) {
- this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
- return this;
- },
-
- // Clears all callbacks previously bound to the view by `delegateEvents`.
- // You usually don't need to use this, but may wish to if you have multiple
- // Backbone views attached to the same DOM element.
- undelegateEvents: function() {
- if (this.$el) this.$el.off('.delegateEvents' + this.cid);
- return this;
- },
-
- // A finer-grained `undelegateEvents` for removing a single delegated event.
- // `selector` and `listener` are both optional.
- undelegate: function(eventName, selector, listener) {
- this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener);
- return this;
- },
-
- // Produces a DOM element to be assigned to your view. Exposed for
- // subclasses using an alternative DOM manipulation API.
- _createElement: function(tagName) {
- return document.createElement(tagName);
- },
-
- // Ensure that the View has a DOM element to render into.
- // If `this.el` is a string, pass it through `$()`, take the first
- // matching element, and re-assign it to `el`. Otherwise, create
- // an element from the `id`, `className` and `tagName` properties.
- _ensureElement: function() {
- if (!this.el) {
- var attrs = _.extend({}, _.result(this, 'attributes'));
- if (this.id) attrs.id = _.result(this, 'id');
- if (this.className) attrs['class'] = _.result(this, 'className');
- this.setElement(this._createElement(_.result(this, 'tagName')));
- this._setAttributes(attrs);
- } else {
- this.setElement(_.result(this, 'el'));
- }
- },
-
- // Set attributes from a hash on this view's element. Exposed for
- // subclasses using an alternative DOM manipulation API.
- _setAttributes: function(attributes) {
- this.$el.attr(attributes);
- }
-
- });
-
- // Backbone.sync
- // -------------
-
- // Override this function to change the manner in which Backbone persists
- // models to the server. You will be passed the type of request, and the
- // model in question. By default, makes a RESTful Ajax request
- // to the model's `url()`. Some possible customizations could be:
- //
- // * Use `setTimeout` to batch rapid-fire updates into a single request.
- // * Send up the models as XML instead of JSON.
- // * Persist models via WebSockets instead of Ajax.
- //
- // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
- // as `POST`, with a `_method` parameter containing the true HTTP method,
- // as well as all requests with the body as `application/x-www-form-urlencoded`
- // instead of `application/json` with the model in a param named `model`.
- // Useful when interfacing with server-side languages like **PHP** that make
- // it difficult to read the body of `PUT` requests.
- Backbone.sync = function(method, model, options) {
- var type = methodMap[method];
-
- // Default options, unless specified.
- _.defaults(options || (options = {}), {
- emulateHTTP: Backbone.emulateHTTP,
- emulateJSON: Backbone.emulateJSON
- });
-
- // Default JSON-request options.
- var params = {type: type, dataType: 'json'};
-
- // Ensure that we have a URL.
- if (!options.url) {
- params.url = _.result(model, 'url') || urlError();
- }
-
- // Ensure that we have the appropriate request data.
- if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
- params.contentType = 'application/json';
- params.data = JSON.stringify(options.attrs || model.toJSON(options));
- }
-
- // For older servers, emulate JSON by encoding the request into an HTML-form.
- if (options.emulateJSON) {
- params.contentType = 'application/x-www-form-urlencoded';
- params.data = params.data ? {model: params.data} : {};
- }
-
- // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
- // And an `X-HTTP-Method-Override` header.
- if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
- params.type = 'POST';
- if (options.emulateJSON) params.data._method = type;
- var beforeSend = options.beforeSend;
- options.beforeSend = function(xhr) {
- xhr.setRequestHeader('X-HTTP-Method-Override', type);
- if (beforeSend) return beforeSend.apply(this, arguments);
- };
- }
-
- // Don't process data on a non-GET request.
- if (params.type !== 'GET' && !options.emulateJSON) {
- params.processData = false;
- }
-
- // Pass along `textStatus` and `errorThrown` from jQuery.
- var error = options.error;
- options.error = function(xhr, textStatus, errorThrown) {
- options.textStatus = textStatus;
- options.errorThrown = errorThrown;
- if (error) error.call(options.context, xhr, textStatus, errorThrown);
- };
-
- // Make the request, allowing the user to override any Ajax options.
- var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
- model.trigger('request', model, xhr, options);
- return xhr;
- };
-
- // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
- var methodMap = {
- 'create': 'POST',
- 'update': 'PUT',
- 'patch': 'PATCH',
- 'delete': 'DELETE',
- 'read': 'GET'
- };
-
- // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
- // Override this if you'd like to use a different library.
- Backbone.ajax = function() {
- return Backbone.$.ajax.apply(Backbone.$, arguments);
- };
-
- // Backbone.Router
- // ---------------
-
- // Routers map faux-URLs to actions, and fire events when routes are
- // matched. Creating a new one sets its `routes` hash, if not set statically.
- var Router = Backbone.Router = function(options) {
- options || (options = {});
- if (options.routes) this.routes = options.routes;
- this._bindRoutes();
- this.initialize.apply(this, arguments);
- };
-
- // Cached regular expressions for matching named param parts and splatted
- // parts of route strings.
- var optionalParam = /\((.*?)\)/g;
- var namedParam = /(\(\?)?:\w+/g;
- var splatParam = /\*\w+/g;
- var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
-
- // Set up all inheritable **Backbone.Router** properties and methods.
- _.extend(Router.prototype, Events, {
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // Manually bind a single named route to a callback. For example:
- //
- // this.route('search/:query/p:num', 'search', function(query, num) {
- // ...
- // });
- //
- route: function(route, name, callback) {
- if (!_.isRegExp(route)) route = this._routeToRegExp(route);
- if (_.isFunction(name)) {
- callback = name;
- name = '';
- }
- if (!callback) callback = this[name];
- var router = this;
- Backbone.history.route(route, function(fragment) {
- var args = router._extractParameters(route, fragment);
- if (router.execute(callback, args, name) !== false) {
- router.trigger.apply(router, ['route:' + name].concat(args));
- router.trigger('route', name, args);
- Backbone.history.trigger('route', router, name, args);
- }
- });
- return this;
- },
-
- // Execute a route handler with the provided parameters. This is an
- // excellent place to do pre-route setup or post-route cleanup.
- execute: function(callback, args, name) {
- if (callback) callback.apply(this, args);
- },
-
- // Simple proxy to `Backbone.history` to save a fragment into the history.
- navigate: function(fragment, options) {
- Backbone.history.navigate(fragment, options);
- return this;
- },
-
- // Bind all defined routes to `Backbone.history`. We have to reverse the
- // order of the routes here to support behavior where the most general
- // routes can be defined at the bottom of the route map.
- _bindRoutes: function() {
- if (!this.routes) return;
- this.routes = _.result(this, 'routes');
- var route, routes = _.keys(this.routes);
- while ((route = routes.pop()) != null) {
- this.route(route, this.routes[route]);
- }
- },
-
- // Convert a route string into a regular expression, suitable for matching
- // against the current location hash.
- _routeToRegExp: function(route) {
- route = route.replace(escapeRegExp, '\\$&')
- .replace(optionalParam, '(?:$1)?')
- .replace(namedParam, function(match, optional) {
- return optional ? match : '([^/?]+)';
- })
- .replace(splatParam, '([^?]*?)');
- return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
- },
-
- // Given a route, and a URL fragment that it matches, return the array of
- // extracted decoded parameters. Empty or unmatched parameters will be
- // treated as `null` to normalize cross-browser behavior.
- _extractParameters: function(route, fragment) {
- var params = route.exec(fragment).slice(1);
- return _.map(params, function(param, i) {
- // Don't decode the search params.
- if (i === params.length - 1) return param || null;
- return param ? decodeURIComponent(param) : null;
- });
- }
-
- });
-
- // Backbone.History
- // ----------------
-
- // Handles cross-browser history management, based on either
- // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
- // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
- // and URL fragments. If the browser supports neither (old IE, natch),
- // falls back to polling.
- var History = Backbone.History = function() {
- this.handlers = [];
- this.checkUrl = _.bind(this.checkUrl, this);
-
- // Ensure that `History` can be used outside of the browser.
- if (typeof window !== 'undefined') {
- this.location = window.location;
- this.history = window.history;
- }
- };
-
- // Cached regex for stripping a leading hash/slash and trailing space.
- var routeStripper = /^[#\/]|\s+$/g;
-
- // Cached regex for stripping leading and trailing slashes.
- var rootStripper = /^\/+|\/+$/g;
-
- // Cached regex for stripping urls of hash.
- var pathStripper = /#.*$/;
-
- // Has the history handling already been started?
- History.started = false;
-
- // Set up all inheritable **Backbone.History** properties and methods.
- _.extend(History.prototype, Events, {
-
- // The default interval to poll for hash changes, if necessary, is
- // twenty times a second.
- interval: 50,
-
- // Are we at the app root?
- atRoot: function() {
- var path = this.location.pathname.replace(/[^\/]$/, '$&/');
- return path === this.root && !this.getSearch();
- },
-
- // Does the pathname match the root?
- matchRoot: function() {
- var path = this.decodeFragment(this.location.pathname);
- var rootPath = path.slice(0, this.root.length - 1) + '/';
- return rootPath === this.root;
- },
-
- // Unicode characters in `location.pathname` are percent encoded so they're
- // decoded for comparison. `%25` should not be decoded since it may be part
- // of an encoded parameter.
- decodeFragment: function(fragment) {
- return decodeURI(fragment.replace(/%25/g, '%2525'));
- },
-
- // In IE6, the hash fragment and search params are incorrect if the
- // fragment contains `?`.
- getSearch: function() {
- var match = this.location.href.replace(/#.*/, '').match(/\?.+/);
- return match ? match[0] : '';
- },
-
- // Gets the true hash value. Cannot use location.hash directly due to bug
- // in Firefox where location.hash will always be decoded.
- getHash: function(window) {
- var match = (window || this).location.href.match(/#(.*)$/);
- return match ? match[1] : '';
- },
-
- // Get the pathname and search params, without the root.
- getPath: function() {
- var path = this.decodeFragment(
- this.location.pathname + this.getSearch()
- ).slice(this.root.length - 1);
- return path.charAt(0) === '/' ? path.slice(1) : path;
- },
-
- // Get the cross-browser normalized URL fragment from the path or hash.
- getFragment: function(fragment) {
- if (fragment == null) {
- if (this._usePushState || !this._wantsHashChange) {
- fragment = this.getPath();
- } else {
- fragment = this.getHash();
- }
- }
- return fragment.replace(routeStripper, '');
- },
-
- // Start the hash change handling, returning `true` if the current URL matches
- // an existing route, and `false` otherwise.
- start: function(options) {
- if (History.started) throw new Error('Backbone.history has already been started');
- History.started = true;
-
- // Figure out the initial configuration. Do we need an iframe?
- // Is pushState desired ... is it available?
- this.options = _.extend({root: '/'}, this.options, options);
- this.root = this.options.root;
- this._wantsHashChange = this.options.hashChange !== false;
- this._hasHashChange = 'onhashchange' in window && (document.documentMode === void 0 || document.documentMode > 7);
- this._useHashChange = this._wantsHashChange && this._hasHashChange;
- this._wantsPushState = !!this.options.pushState;
- this._hasPushState = !!(this.history && this.history.pushState);
- this._usePushState = this._wantsPushState && this._hasPushState;
- this.fragment = this.getFragment();
-
- // Normalize root to always include a leading and trailing slash.
- this.root = ('/' + this.root + '/').replace(rootStripper, '/');
-
- // Transition from hashChange to pushState or vice versa if both are
- // requested.
- if (this._wantsHashChange && this._wantsPushState) {
-
- // If we've started off with a route from a `pushState`-enabled
- // browser, but we're currently in a browser that doesn't support it...
- if (!this._hasPushState && !this.atRoot()) {
- var rootPath = this.root.slice(0, -1) || '/';
- this.location.replace(rootPath + '#' + this.getPath());
- // Return immediately as browser will do redirect to new url
- return true;
-
- // Or if we've started out with a hash-based route, but we're currently
- // in a browser where it could be `pushState`-based instead...
- } else if (this._hasPushState && this.atRoot()) {
- this.navigate(this.getHash(), {replace: true});
- }
-
- }
-
- // Proxy an iframe to handle location events if the browser doesn't
- // support the `hashchange` event, HTML5 history, or the user wants
- // `hashChange` but not `pushState`.
- if (!this._hasHashChange && this._wantsHashChange && !this._usePushState) {
- this.iframe = document.createElement('iframe');
- this.iframe.src = 'javascript:0';
- this.iframe.style.display = 'none';
- this.iframe.tabIndex = -1;
- var body = document.body;
- // Using `appendChild` will throw on IE < 9 if the document is not ready.
- var iWindow = body.insertBefore(this.iframe, body.firstChild).contentWindow;
- iWindow.document.open();
- iWindow.document.close();
- iWindow.location.hash = '#' + this.fragment;
- }
-
- // Add a cross-platform `addEventListener` shim for older browsers.
- var addEventListener = window.addEventListener || function(eventName, listener) {
- return attachEvent('on' + eventName, listener);
- };
-
- // Depending on whether we're using pushState or hashes, and whether
- // 'onhashchange' is supported, determine how we check the URL state.
- if (this._usePushState) {
- addEventListener('popstate', this.checkUrl, false);
- } else if (this._useHashChange && !this.iframe) {
- addEventListener('hashchange', this.checkUrl, false);
- } else if (this._wantsHashChange) {
- this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
- }
-
- if (!this.options.silent) return this.loadUrl();
- },
-
- // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
- // but possibly useful for unit testing Routers.
- stop: function() {
- // Add a cross-platform `removeEventListener` shim for older browsers.
- var removeEventListener = window.removeEventListener || function(eventName, listener) {
- return detachEvent('on' + eventName, listener);
- };
-
- // Remove window listeners.
- if (this._usePushState) {
- removeEventListener('popstate', this.checkUrl, false);
- } else if (this._useHashChange && !this.iframe) {
- removeEventListener('hashchange', this.checkUrl, false);
- }
-
- // Clean up the iframe if necessary.
- if (this.iframe) {
- document.body.removeChild(this.iframe);
- this.iframe = null;
- }
-
- // Some environments will throw when clearing an undefined interval.
- if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);
- History.started = false;
- },
-
- // Add a route to be tested when the fragment changes. Routes added later
- // may override previous routes.
- route: function(route, callback) {
- this.handlers.unshift({route: route, callback: callback});
- },
-
- // Checks the current URL to see if it has changed, and if it has,
- // calls `loadUrl`, normalizing across the hidden iframe.
- checkUrl: function(e) {
- var current = this.getFragment();
-
- // If the user pressed the back button, the iframe's hash will have
- // changed and we should use that for comparison.
- if (current === this.fragment && this.iframe) {
- current = this.getHash(this.iframe.contentWindow);
- }
-
- if (current === this.fragment) return false;
- if (this.iframe) this.navigate(current);
- this.loadUrl();
- },
-
- // Attempt to load the current URL fragment. If a route succeeds with a
- // match, returns `true`. If no defined routes matches the fragment,
- // returns `false`.
- loadUrl: function(fragment) {
- // If the root doesn't match, no routes can match either.
- if (!this.matchRoot()) return false;
- fragment = this.fragment = this.getFragment(fragment);
- return _.some(this.handlers, function(handler) {
- if (handler.route.test(fragment)) {
- handler.callback(fragment);
- return true;
- }
- });
- },
-
- // Save a fragment into the hash history, or replace the URL state if the
- // 'replace' option is passed. You are responsible for properly URL-encoding
- // the fragment in advance.
- //
- // The options object can contain `trigger: true` if you wish to have the
- // route callback be fired (not usually desirable), or `replace: true`, if
- // you wish to modify the current URL without adding an entry to the history.
- navigate: function(fragment, options) {
- if (!History.started) return false;
- if (!options || options === true) options = {trigger: !!options};
-
- // Normalize the fragment.
- fragment = this.getFragment(fragment || '');
-
- // Don't include a trailing slash on the root.
- var rootPath = this.root;
- if (fragment === '' || fragment.charAt(0) === '?') {
- rootPath = rootPath.slice(0, -1) || '/';
- }
- var url = rootPath + fragment;
-
- // Strip the hash and decode for matching.
- fragment = this.decodeFragment(fragment.replace(pathStripper, ''));
-
- if (this.fragment === fragment) return;
- this.fragment = fragment;
-
- // If pushState is available, we use it to set the fragment as a real URL.
- if (this._usePushState) {
- this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
-
- // If hash changes haven't been explicitly disabled, update the hash
- // fragment to store history.
- } else if (this._wantsHashChange) {
- this._updateHash(this.location, fragment, options.replace);
- if (this.iframe && fragment !== this.getHash(this.iframe.contentWindow)) {
- var iWindow = this.iframe.contentWindow;
-
- // Opening and closing the iframe tricks IE7 and earlier to push a
- // history entry on hash-tag change. When replace is true, we don't
- // want this.
- if (!options.replace) {
- iWindow.document.open();
- iWindow.document.close();
- }
-
- this._updateHash(iWindow.location, fragment, options.replace);
- }
-
- // If you've told us that you explicitly don't want fallback hashchange-
- // based history, then `navigate` becomes a page refresh.
- } else {
- return this.location.assign(url);
- }
- if (options.trigger) return this.loadUrl(fragment);
- },
-
- // Update the hash location, either replacing the current entry, or adding
- // a new one to the browser history.
- _updateHash: function(location, fragment, replace) {
- if (replace) {
- var href = location.href.replace(/(javascript:|#).*$/, '');
- location.replace(href + '#' + fragment);
- } else {
- // Some browsers require that `hash` contains a leading #.
- location.hash = '#' + fragment;
- }
- }
-
- });
-
- // Create the default Backbone.history.
- Backbone.history = new History;
-
- // Helpers
- // -------
-
- // Helper function to correctly set up the prototype chain for subclasses.
- // Similar to `goog.inherits`, but uses a hash of prototype properties and
- // class properties to be extended.
- var extend = function(protoProps, staticProps) {
- var parent = this;
- var child;
-
- // The constructor function for the new subclass is either defined by you
- // (the "constructor" property in your `extend` definition), or defaulted
- // by us to simply call the parent constructor.
- if (protoProps && _.has(protoProps, 'constructor')) {
- child = protoProps.constructor;
- } else {
- child = function(){ return parent.apply(this, arguments); };
- }
-
- // Add static properties to the constructor function, if supplied.
- _.extend(child, parent, staticProps);
-
- // Set the prototype chain to inherit from `parent`, without calling
- // `parent`'s constructor function and add the prototype properties.
- child.prototype = _.create(parent.prototype, protoProps);
- child.prototype.constructor = child;
-
- // Set a convenience property in case the parent's prototype is needed
- // later.
- child.__super__ = parent.prototype;
-
- return child;
- };
-
- // Set up inheritance for the model, collection, router, view and history.
- Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
-
- // Throw an error when a URL is needed, and none is supplied.
- var urlError = function() {
- throw new Error('A "url" property or function must be specified');
- };
-
- // Wrap an optional error callback with a fallback error event.
- var wrapError = function(model, options) {
- var error = options.error;
- options.error = function(resp) {
- if (error) error.call(options.context, model, resp, options);
- model.trigger('error', model, resp, options);
- };
- };
-
- return Backbone;
-});
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/collection.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/collection.js
deleted file mode 100644
index dd98aca5..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/collection.js
+++ /dev/null
@@ -1,1998 +0,0 @@
-(function() {
-
- var a, b, c, d, e, col, otherCol;
-
- QUnit.module('Backbone.Collection', {
-
- beforeEach: function(assert) {
- a = new Backbone.Model({id: 3, label: 'a'});
- b = new Backbone.Model({id: 2, label: 'b'});
- c = new Backbone.Model({id: 1, label: 'c'});
- d = new Backbone.Model({id: 0, label: 'd'});
- e = null;
- col = new Backbone.Collection([a, b, c, d]);
- otherCol = new Backbone.Collection();
- }
-
- });
-
- QUnit.test('new and sort', function(assert) {
- assert.expect(6);
- var counter = 0;
- col.on('sort', function(){ counter++; });
- assert.deepEqual(col.pluck('label'), ['a', 'b', 'c', 'd']);
- col.comparator = function(m1, m2) {
- return m1.id > m2.id ? -1 : 1;
- };
- col.sort();
- assert.equal(counter, 1);
- assert.deepEqual(col.pluck('label'), ['a', 'b', 'c', 'd']);
- col.comparator = function(model) { return model.id; };
- col.sort();
- assert.equal(counter, 2);
- assert.deepEqual(col.pluck('label'), ['d', 'c', 'b', 'a']);
- assert.equal(col.length, 4);
- });
-
- QUnit.test('String comparator.', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection([
- {id: 3},
- {id: 1},
- {id: 2}
- ], {comparator: 'id'});
- assert.deepEqual(collection.pluck('id'), [1, 2, 3]);
- });
-
- QUnit.test('new and parse', function(assert) {
- assert.expect(3);
- var Collection = Backbone.Collection.extend({
- parse: function(data) {
- return _.filter(data, function(datum) {
- return datum.a % 2 === 0;
- });
- }
- });
- var models = [{a: 1}, {a: 2}, {a: 3}, {a: 4}];
- var collection = new Collection(models, {parse: true});
- assert.strictEqual(collection.length, 2);
- assert.strictEqual(collection.first().get('a'), 2);
- assert.strictEqual(collection.last().get('a'), 4);
- });
-
- QUnit.test('clone preserves model and comparator', function(assert) {
- assert.expect(3);
- var Model = Backbone.Model.extend();
- var comparator = function(model){ return model.id; };
-
- var collection = new Backbone.Collection([{id: 1}], {
- model: Model,
- comparator: comparator
- }).clone();
- collection.add({id: 2});
- assert.ok(collection.at(0) instanceof Model);
- assert.ok(collection.at(1) instanceof Model);
- assert.strictEqual(collection.comparator, comparator);
- });
-
- QUnit.test('get', function(assert) {
- assert.expect(6);
- assert.equal(col.get(0), d);
- assert.equal(col.get(d.clone()), d);
- assert.equal(col.get(2), b);
- assert.equal(col.get({id: 1}), c);
- assert.equal(col.get(c.clone()), c);
- assert.equal(col.get(col.first().cid), col.first());
- });
-
- QUnit.test('get with non-default ids', function(assert) {
- assert.expect(5);
- var MongoModel = Backbone.Model.extend({idAttribute: '_id'});
- var model = new MongoModel({_id: 100});
- var collection = new Backbone.Collection([model], {model: MongoModel});
- assert.equal(collection.get(100), model);
- assert.equal(collection.get(model.cid), model);
- assert.equal(collection.get(model), model);
- assert.equal(collection.get(101), void 0);
-
- var collection2 = new Backbone.Collection();
- collection2.model = MongoModel;
- collection2.add(model.attributes);
- assert.equal(collection2.get(model.clone()), collection2.first());
- });
-
- QUnit.test('has', function(assert) {
- assert.expect(15);
- assert.ok(col.has(a));
- assert.ok(col.has(b));
- assert.ok(col.has(c));
- assert.ok(col.has(d));
- assert.ok(col.has(a.id));
- assert.ok(col.has(b.id));
- assert.ok(col.has(c.id));
- assert.ok(col.has(d.id));
- assert.ok(col.has(a.cid));
- assert.ok(col.has(b.cid));
- assert.ok(col.has(c.cid));
- assert.ok(col.has(d.cid));
- var outsider = new Backbone.Model({id: 4});
- assert.notOk(col.has(outsider));
- assert.notOk(col.has(outsider.id));
- assert.notOk(col.has(outsider.cid));
- });
-
- QUnit.test('update index when id changes', function(assert) {
- assert.expect(4);
- var collection = new Backbone.Collection();
- collection.add([
- {id: 0, name: 'one'},
- {id: 1, name: 'two'}
- ]);
- var one = collection.get(0);
- assert.equal(one.get('name'), 'one');
- collection.on('change:name', function(model) { assert.ok(this.get(model)); });
- one.set({name: 'dalmatians', id: 101});
- assert.equal(collection.get(0), null);
- assert.equal(collection.get(101).get('name'), 'dalmatians');
- });
-
- QUnit.test('at', function(assert) {
- assert.expect(2);
- assert.equal(col.at(2), c);
- assert.equal(col.at(-2), c);
- });
-
- QUnit.test('pluck', function(assert) {
- assert.expect(1);
- assert.equal(col.pluck('label').join(' '), 'a b c d');
- });
-
- QUnit.test('add', function(assert) {
- assert.expect(14);
- var added, opts, secondAdded;
- added = opts = secondAdded = null;
- e = new Backbone.Model({id: 10, label: 'e'});
- otherCol.add(e);
- otherCol.on('add', function() {
- secondAdded = true;
- });
- col.on('add', function(model, collection, options){
- added = model.get('label');
- opts = options;
- });
- col.add(e, {amazing: true});
- assert.equal(added, 'e');
- assert.equal(col.length, 5);
- assert.equal(col.last(), e);
- assert.equal(otherCol.length, 1);
- assert.equal(secondAdded, null);
- assert.ok(opts.amazing);
-
- var f = new Backbone.Model({id: 20, label: 'f'});
- var g = new Backbone.Model({id: 21, label: 'g'});
- var h = new Backbone.Model({id: 22, label: 'h'});
- var atCol = new Backbone.Collection([f, g, h]);
- assert.equal(atCol.length, 3);
- atCol.add(e, {at: 1});
- assert.equal(atCol.length, 4);
- assert.equal(atCol.at(1), e);
- assert.equal(atCol.last(), h);
-
- var coll = new Backbone.Collection(new Array(2));
- var addCount = 0;
- coll.on('add', function(){
- addCount += 1;
- });
- coll.add([undefined, f, g]);
- assert.equal(coll.length, 5);
- assert.equal(addCount, 3);
- coll.add(new Array(4));
- assert.equal(coll.length, 9);
- assert.equal(addCount, 7);
- });
-
- QUnit.test('add multiple models', function(assert) {
- assert.expect(6);
- var collection = new Backbone.Collection([{at: 0}, {at: 1}, {at: 9}]);
- collection.add([{at: 2}, {at: 3}, {at: 4}, {at: 5}, {at: 6}, {at: 7}, {at: 8}], {at: 2});
- for (var i = 0; i <= 5; i++) {
- assert.equal(collection.at(i).get('at'), i);
- }
- });
-
- QUnit.test('add; at should have preference over comparator', function(assert) {
- assert.expect(1);
- var Col = Backbone.Collection.extend({
- comparator: function(m1, m2) {
- return m1.id > m2.id ? -1 : 1;
- }
- });
-
- var collection = new Col([{id: 2}, {id: 3}]);
- collection.add(new Backbone.Model({id: 1}), {at: 1});
-
- assert.equal(collection.pluck('id').join(' '), '3 1 2');
- });
-
- QUnit.test('add; at should add to the end if the index is out of bounds', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection([{id: 2}, {id: 3}]);
- collection.add(new Backbone.Model({id: 1}), {at: 5});
-
- assert.equal(collection.pluck('id').join(' '), '2 3 1');
- });
-
- QUnit.test("can't add model to collection twice", function(assert) {
- var collection = new Backbone.Collection([{id: 1}, {id: 2}, {id: 1}, {id: 2}, {id: 3}]);
- assert.equal(collection.pluck('id').join(' '), '1 2 3');
- });
-
- QUnit.test("can't add different model with same id to collection twice", function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection;
- collection.unshift({id: 101});
- collection.add({id: 101});
- assert.equal(collection.length, 1);
- });
-
- QUnit.test('merge in duplicate models with {merge: true}', function(assert) {
- assert.expect(3);
- var collection = new Backbone.Collection;
- collection.add([{id: 1, name: 'Moe'}, {id: 2, name: 'Curly'}, {id: 3, name: 'Larry'}]);
- collection.add({id: 1, name: 'Moses'});
- assert.equal(collection.first().get('name'), 'Moe');
- collection.add({id: 1, name: 'Moses'}, {merge: true});
- assert.equal(collection.first().get('name'), 'Moses');
- collection.add({id: 1, name: 'Tim'}, {merge: true, silent: true});
- assert.equal(collection.first().get('name'), 'Tim');
- });
-
- QUnit.test('add model to multiple collections', function(assert) {
- assert.expect(10);
- var counter = 0;
- var m = new Backbone.Model({id: 10, label: 'm'});
- m.on('add', function(model, collection) {
- counter++;
- assert.equal(m, model);
- if (counter > 1) {
- assert.equal(collection, col2);
- } else {
- assert.equal(collection, col1);
- }
- });
- var col1 = new Backbone.Collection([]);
- col1.on('add', function(model, collection) {
- assert.equal(m, model);
- assert.equal(col1, collection);
- });
- var col2 = new Backbone.Collection([]);
- col2.on('add', function(model, collection) {
- assert.equal(m, model);
- assert.equal(col2, collection);
- });
- col1.add(m);
- assert.equal(m.collection, col1);
- col2.add(m);
- assert.equal(m.collection, col1);
- });
-
- QUnit.test('add model with parse', function(assert) {
- assert.expect(1);
- var Model = Backbone.Model.extend({
- parse: function(obj) {
- obj.value += 1;
- return obj;
- }
- });
-
- var Col = Backbone.Collection.extend({model: Model});
- var collection = new Col;
- collection.add({value: 1}, {parse: true});
- assert.equal(collection.at(0).get('value'), 2);
- });
-
- QUnit.test('add with parse and merge', function(assert) {
- var collection = new Backbone.Collection();
- collection.parse = function(attrs) {
- return _.map(attrs, function(model) {
- if (model.model) return model.model;
- return model;
- });
- };
- collection.add({id: 1});
- collection.add({model: {id: 1, name: 'Alf'}}, {parse: true, merge: true});
- assert.equal(collection.first().get('name'), 'Alf');
- });
-
- QUnit.test('add model to collection with sort()-style comparator', function(assert) {
- assert.expect(3);
- var collection = new Backbone.Collection;
- collection.comparator = function(m1, m2) {
- return m1.get('name') < m2.get('name') ? -1 : 1;
- };
- var tom = new Backbone.Model({name: 'Tom'});
- var rob = new Backbone.Model({name: 'Rob'});
- var tim = new Backbone.Model({name: 'Tim'});
- collection.add(tom);
- collection.add(rob);
- collection.add(tim);
- assert.equal(collection.indexOf(rob), 0);
- assert.equal(collection.indexOf(tim), 1);
- assert.equal(collection.indexOf(tom), 2);
- });
-
- QUnit.test('comparator that depends on `this`', function(assert) {
- assert.expect(2);
- var collection = new Backbone.Collection;
- collection.negative = function(num) {
- return -num;
- };
- collection.comparator = function(model) {
- return this.negative(model.id);
- };
- collection.add([{id: 1}, {id: 2}, {id: 3}]);
- assert.deepEqual(collection.pluck('id'), [3, 2, 1]);
- collection.comparator = function(m1, m2) {
- return this.negative(m2.id) - this.negative(m1.id);
- };
- collection.sort();
- assert.deepEqual(collection.pluck('id'), [1, 2, 3]);
- });
-
- QUnit.test('remove', function(assert) {
- assert.expect(12);
- var removed = null;
- var result = null;
- col.on('remove', function(model, collection, options) {
- removed = model.get('label');
- assert.equal(options.index, 3);
- assert.equal(collection.get(model), undefined, '#3693: model cannot be fetched from collection');
- });
- result = col.remove(d);
- assert.equal(removed, 'd');
- assert.strictEqual(result, d);
- //if we try to remove d again, it's not going to actually get removed
- result = col.remove(d);
- assert.strictEqual(result, undefined);
- assert.equal(col.length, 3);
- assert.equal(col.first(), a);
- col.off();
- result = col.remove([c, d]);
- assert.equal(result.length, 1, 'only returns removed models');
- assert.equal(result[0], c, 'only returns removed models');
- result = col.remove([c, b]);
- assert.equal(result.length, 1, 'only returns removed models');
- assert.equal(result[0], b, 'only returns removed models');
- result = col.remove([]);
- assert.deepEqual(result, [], 'returns empty array when nothing removed');
- });
-
- QUnit.test('add and remove return values', function(assert) {
- assert.expect(13);
- var Even = Backbone.Model.extend({
- validate: function(attrs) {
- if (attrs.id % 2 !== 0) return 'odd';
- }
- });
- var collection = new Backbone.Collection;
- collection.model = Even;
-
- var list = collection.add([{id: 2}, {id: 4}], {validate: true});
- assert.equal(list.length, 2);
- assert.ok(list[0] instanceof Backbone.Model);
- assert.equal(list[1], collection.last());
- assert.equal(list[1].get('id'), 4);
-
- list = collection.add([{id: 3}, {id: 6}], {validate: true});
- assert.equal(collection.length, 3);
- assert.equal(list[0], false);
- assert.equal(list[1].get('id'), 6);
-
- var result = collection.add({id: 6});
- assert.equal(result.cid, list[1].cid);
-
- result = collection.remove({id: 6});
- assert.equal(collection.length, 2);
- assert.equal(result.id, 6);
-
- list = collection.remove([{id: 2}, {id: 8}]);
- assert.equal(collection.length, 1);
- assert.equal(list[0].get('id'), 2);
- assert.equal(list[1], null);
- });
-
- QUnit.test('shift and pop', function(assert) {
- assert.expect(2);
- var collection = new Backbone.Collection([{a: 'a'}, {b: 'b'}, {c: 'c'}]);
- assert.equal(collection.shift().get('a'), 'a');
- assert.equal(collection.pop().get('c'), 'c');
- });
-
- QUnit.test('slice', function(assert) {
- assert.expect(2);
- var collection = new Backbone.Collection([{a: 'a'}, {b: 'b'}, {c: 'c'}]);
- var array = collection.slice(1, 3);
- assert.equal(array.length, 2);
- assert.equal(array[0].get('b'), 'b');
- });
-
- QUnit.test('events are unbound on remove', function(assert) {
- assert.expect(3);
- var counter = 0;
- var dj = new Backbone.Model();
- var emcees = new Backbone.Collection([dj]);
- emcees.on('change', function(){ counter++; });
- dj.set({name: 'Kool'});
- assert.equal(counter, 1);
- emcees.reset([]);
- assert.equal(dj.collection, undefined);
- dj.set({name: 'Shadow'});
- assert.equal(counter, 1);
- });
-
- QUnit.test('remove in multiple collections', function(assert) {
- assert.expect(7);
- var modelData = {
- id: 5,
- title: 'Othello'
- };
- var passed = false;
- var m1 = new Backbone.Model(modelData);
- var m2 = new Backbone.Model(modelData);
- m2.on('remove', function() {
- passed = true;
- });
- var col1 = new Backbone.Collection([m1]);
- var col2 = new Backbone.Collection([m2]);
- assert.notEqual(m1, m2);
- assert.ok(col1.length === 1);
- assert.ok(col2.length === 1);
- col1.remove(m1);
- assert.equal(passed, false);
- assert.ok(col1.length === 0);
- col2.remove(m1);
- assert.ok(col2.length === 0);
- assert.equal(passed, true);
- });
-
- QUnit.test('remove same model in multiple collection', function(assert) {
- assert.expect(16);
- var counter = 0;
- var m = new Backbone.Model({id: 5, title: 'Othello'});
- m.on('remove', function(model, collection) {
- counter++;
- assert.equal(m, model);
- if (counter > 1) {
- assert.equal(collection, col1);
- } else {
- assert.equal(collection, col2);
- }
- });
- var col1 = new Backbone.Collection([m]);
- col1.on('remove', function(model, collection) {
- assert.equal(m, model);
- assert.equal(col1, collection);
- });
- var col2 = new Backbone.Collection([m]);
- col2.on('remove', function(model, collection) {
- assert.equal(m, model);
- assert.equal(col2, collection);
- });
- assert.equal(col1, m.collection);
- col2.remove(m);
- assert.ok(col2.length === 0);
- assert.ok(col1.length === 1);
- assert.equal(counter, 1);
- assert.equal(col1, m.collection);
- col1.remove(m);
- assert.equal(null, m.collection);
- assert.ok(col1.length === 0);
- assert.equal(counter, 2);
- });
-
- QUnit.test('model destroy removes from all collections', function(assert) {
- assert.expect(3);
- var m = new Backbone.Model({id: 5, title: 'Othello'});
- m.sync = function(method, model, options) { options.success(); };
- var col1 = new Backbone.Collection([m]);
- var col2 = new Backbone.Collection([m]);
- m.destroy();
- assert.ok(col1.length === 0);
- assert.ok(col2.length === 0);
- assert.equal(undefined, m.collection);
- });
-
- QUnit.test('Collection: non-persisted model destroy removes from all collections', function(assert) {
- assert.expect(3);
- var m = new Backbone.Model({title: 'Othello'});
- m.sync = function(method, model, options) { throw 'should not be called'; };
- var col1 = new Backbone.Collection([m]);
- var col2 = new Backbone.Collection([m]);
- m.destroy();
- assert.ok(col1.length === 0);
- assert.ok(col2.length === 0);
- assert.equal(undefined, m.collection);
- });
-
- QUnit.test('fetch', function(assert) {
- assert.expect(4);
- var collection = new Backbone.Collection;
- collection.url = '/test';
- collection.fetch();
- assert.equal(this.syncArgs.method, 'read');
- assert.equal(this.syncArgs.model, collection);
- assert.equal(this.syncArgs.options.parse, true);
-
- collection.fetch({parse: false});
- assert.equal(this.syncArgs.options.parse, false);
- });
-
- QUnit.test('fetch with an error response triggers an error event', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection();
- collection.on('error', function() {
- assert.ok(true);
- });
- collection.sync = function(method, model, options) { options.error(); };
- collection.fetch();
- });
-
- QUnit.test('#3283 - fetch with an error response calls error with context', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection();
- var obj = {};
- var options = {
- context: obj,
- error: function() {
- assert.equal(this, obj);
- }
- };
- collection.sync = function(method, model, opts) {
- opts.error.call(opts.context);
- };
- collection.fetch(options);
- });
-
- QUnit.test('ensure fetch only parses once', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection;
- var counter = 0;
- collection.parse = function(models) {
- counter++;
- return models;
- };
- collection.url = '/test';
- collection.fetch();
- this.syncArgs.options.success([]);
- assert.equal(counter, 1);
- });
-
- QUnit.test('create', function(assert) {
- assert.expect(4);
- var collection = new Backbone.Collection;
- collection.url = '/test';
- var model = collection.create({label: 'f'}, {wait: true});
- assert.equal(this.syncArgs.method, 'create');
- assert.equal(this.syncArgs.model, model);
- assert.equal(model.get('label'), 'f');
- assert.equal(model.collection, collection);
- });
-
- QUnit.test('create with validate:true enforces validation', function(assert) {
- assert.expect(3);
- var ValidatingModel = Backbone.Model.extend({
- validate: function(attrs) {
- return 'fail';
- }
- });
- var ValidatingCollection = Backbone.Collection.extend({
- model: ValidatingModel
- });
- var collection = new ValidatingCollection();
- collection.on('invalid', function(coll, error, options) {
- assert.equal(error, 'fail');
- assert.equal(options.validationError, 'fail');
- });
- assert.equal(collection.create({'foo': 'bar'}, {validate: true}), false);
- });
-
- QUnit.test('create will pass extra options to success callback', function(assert) {
- assert.expect(1);
- var Model = Backbone.Model.extend({
- sync: function(method, model, options) {
- _.extend(options, {specialSync: true});
- return Backbone.Model.prototype.sync.call(this, method, model, options);
- }
- });
-
- var Collection = Backbone.Collection.extend({
- model: Model,
- url: '/test'
- });
-
- var collection = new Collection;
-
- var success = function(model, response, options) {
- assert.ok(options.specialSync, 'Options were passed correctly to callback');
- };
-
- collection.create({}, {success: success});
- this.ajaxSettings.success();
- });
-
- QUnit.test('create with wait:true should not call collection.parse', function(assert) {
- assert.expect(0);
- var Collection = Backbone.Collection.extend({
- url: '/test',
- parse: function() {
- assert.ok(false);
- }
- });
-
- var collection = new Collection;
-
- collection.create({}, {wait: true});
- this.ajaxSettings.success();
- });
-
- QUnit.test('a failing create returns model with errors', function(assert) {
- var ValidatingModel = Backbone.Model.extend({
- validate: function(attrs) {
- return 'fail';
- }
- });
- var ValidatingCollection = Backbone.Collection.extend({
- model: ValidatingModel
- });
- var collection = new ValidatingCollection();
- var m = collection.create({foo: 'bar'});
- assert.equal(m.validationError, 'fail');
- assert.equal(collection.length, 1);
- });
-
- QUnit.test('initialize', function(assert) {
- assert.expect(1);
- var Collection = Backbone.Collection.extend({
- initialize: function() {
- this.one = 1;
- }
- });
- var coll = new Collection;
- assert.equal(coll.one, 1);
- });
-
- QUnit.test('toJSON', function(assert) {
- assert.expect(1);
- assert.equal(JSON.stringify(col), '[{"id":3,"label":"a"},{"id":2,"label":"b"},{"id":1,"label":"c"},{"id":0,"label":"d"}]');
- });
-
- QUnit.test('where and findWhere', function(assert) {
- assert.expect(8);
- var model = new Backbone.Model({a: 1});
- var coll = new Backbone.Collection([
- model,
- {a: 1},
- {a: 1, b: 2},
- {a: 2, b: 2},
- {a: 3}
- ]);
- assert.equal(coll.where({a: 1}).length, 3);
- assert.equal(coll.where({a: 2}).length, 1);
- assert.equal(coll.where({a: 3}).length, 1);
- assert.equal(coll.where({b: 1}).length, 0);
- assert.equal(coll.where({b: 2}).length, 2);
- assert.equal(coll.where({a: 1, b: 2}).length, 1);
- assert.equal(coll.findWhere({a: 1}), model);
- assert.equal(coll.findWhere({a: 4}), void 0);
- });
-
- QUnit.test('Underscore methods', function(assert) {
- assert.expect(21);
- assert.equal(col.map(function(model){ return model.get('label'); }).join(' '), 'a b c d');
- assert.equal(col.some(function(model){ return model.id === 100; }), false);
- assert.equal(col.some(function(model){ return model.id === 0; }), true);
- assert.equal(col.reduce(function(m1, m2) {return m1.id > m2.id ? m1 : m2;}).id, 3);
- assert.equal(col.reduceRight(function(m1, m2) {return m1.id > m2.id ? m1 : m2;}).id, 3);
- assert.equal(col.indexOf(b), 1);
- assert.equal(col.size(), 4);
- assert.equal(col.rest().length, 3);
- assert.ok(!_.includes(col.rest(), a));
- assert.ok(_.includes(col.rest(), d));
- assert.ok(!col.isEmpty());
- assert.ok(!_.includes(col.without(d), d));
-
- var wrapped = col.chain();
- assert.equal(wrapped.map('id').max().value(), 3);
- assert.equal(wrapped.map('id').min().value(), 0);
- assert.deepEqual(wrapped
- .filter(function(o){ return o.id % 2 === 0; })
- .map(function(o){ return o.id * 2; })
- .value(),
- [4, 0]);
- assert.deepEqual(col.difference([c, d]), [a, b]);
- assert.ok(col.includes(col.sample()));
-
- var first = col.first();
- assert.deepEqual(col.groupBy(function(model){ return model.id; })[first.id], [first]);
- assert.deepEqual(col.countBy(function(model){ return model.id; }), {0: 1, 1: 1, 2: 1, 3: 1});
- assert.deepEqual(col.sortBy(function(model){ return model.id; })[0], col.at(3));
- assert.ok(col.indexBy('id')[first.id] === first);
- });
-
- QUnit.test('Underscore methods with object-style and property-style iteratee', function(assert) {
- assert.expect(26);
- var model = new Backbone.Model({a: 4, b: 1, e: 3});
- var coll = new Backbone.Collection([
- {a: 1, b: 1},
- {a: 2, b: 1, c: 1},
- {a: 3, b: 1},
- model
- ]);
- assert.equal(coll.find({a: 0}), undefined);
- assert.deepEqual(coll.find({a: 4}), model);
- assert.equal(coll.find('d'), undefined);
- assert.deepEqual(coll.find('e'), model);
- assert.equal(coll.filter({a: 0}), false);
- assert.deepEqual(coll.filter({a: 4}), [model]);
- assert.equal(coll.some({a: 0}), false);
- assert.equal(coll.some({a: 1}), true);
- assert.equal(coll.reject({a: 0}).length, 4);
- assert.deepEqual(coll.reject({a: 4}), _.without(coll.models, model));
- assert.equal(coll.every({a: 0}), false);
- assert.equal(coll.every({b: 1}), true);
- assert.deepEqual(coll.partition({a: 0})[0], []);
- assert.deepEqual(coll.partition({a: 0})[1], coll.models);
- assert.deepEqual(coll.partition({a: 4})[0], [model]);
- assert.deepEqual(coll.partition({a: 4})[1], _.without(coll.models, model));
- assert.deepEqual(coll.map({a: 2}), [false, true, false, false]);
- assert.deepEqual(coll.map('a'), [1, 2, 3, 4]);
- assert.deepEqual(coll.sortBy('a')[3], model);
- assert.deepEqual(coll.sortBy('e')[0], model);
- assert.deepEqual(coll.countBy({a: 4}), {'false': 3, 'true': 1});
- assert.deepEqual(coll.countBy('d'), {'undefined': 4});
- assert.equal(coll.findIndex({b: 1}), 0);
- assert.equal(coll.findIndex({b: 9}), -1);
- assert.equal(coll.findLastIndex({b: 1}), 3);
- assert.equal(coll.findLastIndex({b: 9}), -1);
- });
-
- QUnit.test('reset', function(assert) {
- assert.expect(16);
-
- var resetCount = 0;
- var models = col.models;
- col.on('reset', function() { resetCount += 1; });
- col.reset([]);
- assert.equal(resetCount, 1);
- assert.equal(col.length, 0);
- assert.equal(col.last(), null);
- col.reset(models);
- assert.equal(resetCount, 2);
- assert.equal(col.length, 4);
- assert.equal(col.last(), d);
- col.reset(_.map(models, function(m){ return m.attributes; }));
- assert.equal(resetCount, 3);
- assert.equal(col.length, 4);
- assert.ok(col.last() !== d);
- assert.ok(_.isEqual(col.last().attributes, d.attributes));
- col.reset();
- assert.equal(col.length, 0);
- assert.equal(resetCount, 4);
-
- var f = new Backbone.Model({id: 20, label: 'f'});
- col.reset([undefined, f]);
- assert.equal(col.length, 2);
- assert.equal(resetCount, 5);
-
- col.reset(new Array(4));
- assert.equal(col.length, 4);
- assert.equal(resetCount, 6);
- });
-
- QUnit.test('reset with different values', function(assert) {
- var collection = new Backbone.Collection({id: 1});
- collection.reset({id: 1, a: 1});
- assert.equal(collection.get(1).get('a'), 1);
- });
-
- QUnit.test('same references in reset', function(assert) {
- var model = new Backbone.Model({id: 1});
- var collection = new Backbone.Collection({id: 1});
- collection.reset(model);
- assert.equal(collection.get(1), model);
- });
-
- QUnit.test('reset passes caller options', function(assert) {
- assert.expect(3);
- var Model = Backbone.Model.extend({
- initialize: function(attrs, options) {
- this.modelParameter = options.modelParameter;
- }
- });
- var collection = new (Backbone.Collection.extend({model: Model}))();
- collection.reset([{astring: 'green', anumber: 1}, {astring: 'blue', anumber: 2}], {modelParameter: 'model parameter'});
- assert.equal(collection.length, 2);
- collection.each(function(model) {
- assert.equal(model.modelParameter, 'model parameter');
- });
- });
-
- QUnit.test('reset does not alter options by reference', function(assert) {
- assert.expect(2);
- var collection = new Backbone.Collection([{id: 1}]);
- var origOpts = {};
- collection.on('reset', function(coll, opts){
- assert.equal(origOpts.previousModels, undefined);
- assert.equal(opts.previousModels[0].id, 1);
- });
- collection.reset([], origOpts);
- });
-
- QUnit.test('trigger custom events on models', function(assert) {
- assert.expect(1);
- var fired = null;
- a.on('custom', function() { fired = true; });
- a.trigger('custom');
- assert.equal(fired, true);
- });
-
- QUnit.test('add does not alter arguments', function(assert) {
- assert.expect(2);
- var attrs = {};
- var models = [attrs];
- new Backbone.Collection().add(models);
- assert.equal(models.length, 1);
- assert.ok(attrs === models[0]);
- });
-
- QUnit.test('#714: access `model.collection` in a brand new model.', function(assert) {
- assert.expect(2);
- var collection = new Backbone.Collection;
- collection.url = '/test';
- var Model = Backbone.Model.extend({
- set: function(attrs) {
- assert.equal(attrs.prop, 'value');
- assert.equal(this.collection, collection);
- return this;
- }
- });
- collection.model = Model;
- collection.create({prop: 'value'});
- });
-
- QUnit.test('#574, remove its own reference to the .models array.', function(assert) {
- assert.expect(2);
- var collection = new Backbone.Collection([
- {id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}
- ]);
- assert.equal(collection.length, 6);
- collection.remove(collection.models);
- assert.equal(collection.length, 0);
- });
-
- QUnit.test('#861, adding models to a collection which do not pass validation, with validate:true', function(assert) {
- assert.expect(2);
- var Model = Backbone.Model.extend({
- validate: function(attrs) {
- if (attrs.id === 3) return "id can't be 3";
- }
- });
-
- var Collection = Backbone.Collection.extend({
- model: Model
- });
-
- var collection = new Collection;
- collection.on('invalid', function() { assert.ok(true); });
-
- collection.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}], {validate: true});
- assert.deepEqual(collection.pluck('id'), [1, 2, 4, 5, 6]);
- });
-
- QUnit.test('Invalid models are discarded with validate:true.', function(assert) {
- assert.expect(5);
- var collection = new Backbone.Collection;
- collection.on('test', function() { assert.ok(true); });
- collection.model = Backbone.Model.extend({
- validate: function(attrs){ if (!attrs.valid) return 'invalid'; }
- });
- var model = new collection.model({id: 1, valid: true});
- collection.add([model, {id: 2}], {validate: true});
- model.trigger('test');
- assert.ok(collection.get(model.cid));
- assert.ok(collection.get(1));
- assert.ok(!collection.get(2));
- assert.equal(collection.length, 1);
- });
-
- QUnit.test('multiple copies of the same model', function(assert) {
- assert.expect(3);
- var collection = new Backbone.Collection();
- var model = new Backbone.Model();
- collection.add([model, model]);
- assert.equal(collection.length, 1);
- collection.add([{id: 1}, {id: 1}]);
- assert.equal(collection.length, 2);
- assert.equal(collection.last().id, 1);
- });
-
- QUnit.test('#964 - collection.get return inconsistent', function(assert) {
- assert.expect(2);
- var collection = new Backbone.Collection();
- assert.ok(collection.get(null) === undefined);
- assert.ok(collection.get() === undefined);
- });
-
- QUnit.test('#1112 - passing options.model sets collection.model', function(assert) {
- assert.expect(2);
- var Model = Backbone.Model.extend({});
- var collection = new Backbone.Collection([{id: 1}], {model: Model});
- assert.ok(collection.model === Model);
- assert.ok(collection.at(0) instanceof Model);
- });
-
- QUnit.test('null and undefined are invalid ids.', function(assert) {
- assert.expect(2);
- var model = new Backbone.Model({id: 1});
- var collection = new Backbone.Collection([model]);
- model.set({id: null});
- assert.ok(!collection.get('null'));
- model.set({id: 1});
- model.set({id: undefined});
- assert.ok(!collection.get('undefined'));
- });
-
- QUnit.test('falsy comparator', function(assert) {
- assert.expect(4);
- var Col = Backbone.Collection.extend({
- comparator: function(model){ return model.id; }
- });
- var collection = new Col();
- var colFalse = new Col(null, {comparator: false});
- var colNull = new Col(null, {comparator: null});
- var colUndefined = new Col(null, {comparator: undefined});
- assert.ok(collection.comparator);
- assert.ok(!colFalse.comparator);
- assert.ok(!colNull.comparator);
- assert.ok(colUndefined.comparator);
- });
-
- QUnit.test('#1355 - `options` is passed to success callbacks', function(assert) {
- assert.expect(2);
- var m = new Backbone.Model({x: 1});
- var collection = new Backbone.Collection();
- var opts = {
- opts: true,
- success: function(coll, resp, options) {
- assert.ok(options.opts);
- }
- };
- collection.sync = m.sync = function( method, coll, options ){
- options.success({});
- };
- collection.fetch(opts);
- collection.create(m, opts);
- });
-
- QUnit.test("#1412 - Trigger 'request' and 'sync' events.", function(assert) {
- assert.expect(4);
- var collection = new Backbone.Collection;
- collection.url = '/test';
- Backbone.ajax = function(settings){ settings.success(); };
-
- collection.on('request', function(obj, xhr, options) {
- assert.ok(obj === collection, "collection has correct 'request' event after fetching");
- });
- collection.on('sync', function(obj, response, options) {
- assert.ok(obj === collection, "collection has correct 'sync' event after fetching");
- });
- collection.fetch();
- collection.off();
-
- collection.on('request', function(obj, xhr, options) {
- assert.ok(obj === collection.get(1), "collection has correct 'request' event after one of its models save");
- });
- collection.on('sync', function(obj, response, options) {
- assert.ok(obj === collection.get(1), "collection has correct 'sync' event after one of its models save");
- });
- collection.create({id: 1});
- collection.off();
- });
-
- QUnit.test('#3283 - fetch, create calls success with context', function(assert) {
- assert.expect(2);
- var collection = new Backbone.Collection;
- collection.url = '/test';
- Backbone.ajax = function(settings) {
- settings.success.call(settings.context);
- };
- var obj = {};
- var options = {
- context: obj,
- success: function() {
- assert.equal(this, obj);
- }
- };
-
- collection.fetch(options);
- collection.create({id: 1}, options);
- });
-
- QUnit.test('#1447 - create with wait adds model.', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection;
- var model = new Backbone.Model;
- model.sync = function(method, m, options){ options.success(); };
- collection.on('add', function(){ assert.ok(true); });
- collection.create(model, {wait: true});
- });
-
- QUnit.test('#1448 - add sorts collection after merge.', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection([
- {id: 1, x: 1},
- {id: 2, x: 2}
- ]);
- collection.comparator = function(model){ return model.get('x'); };
- collection.add({id: 1, x: 3}, {merge: true});
- assert.deepEqual(collection.pluck('id'), [2, 1]);
- });
-
- QUnit.test('#1655 - groupBy can be used with a string argument.', function(assert) {
- assert.expect(3);
- var collection = new Backbone.Collection([{x: 1}, {x: 2}]);
- var grouped = collection.groupBy('x');
- assert.strictEqual(_.keys(grouped).length, 2);
- assert.strictEqual(grouped[1][0].get('x'), 1);
- assert.strictEqual(grouped[2][0].get('x'), 2);
- });
-
- QUnit.test('#1655 - sortBy can be used with a string argument.', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection([{x: 3}, {x: 1}, {x: 2}]);
- var values = _.map(collection.sortBy('x'), function(model) {
- return model.get('x');
- });
- assert.deepEqual(values, [1, 2, 3]);
- });
-
- QUnit.test('#1604 - Removal during iteration.', function(assert) {
- assert.expect(0);
- var collection = new Backbone.Collection([{}, {}]);
- collection.on('add', function() {
- collection.at(0).destroy();
- });
- collection.add({}, {at: 0});
- });
-
- QUnit.test('#1638 - `sort` during `add` triggers correctly.', function(assert) {
- var collection = new Backbone.Collection;
- collection.comparator = function(model) { return model.get('x'); };
- var added = [];
- collection.on('add', function(model) {
- model.set({x: 3});
- collection.sort();
- added.push(model.id);
- });
- collection.add([{id: 1, x: 1}, {id: 2, x: 2}]);
- assert.deepEqual(added, [1, 2]);
- });
-
- QUnit.test('fetch parses models by default', function(assert) {
- assert.expect(1);
- var model = {};
- var Collection = Backbone.Collection.extend({
- url: 'test',
- model: Backbone.Model.extend({
- parse: function(resp) {
- assert.strictEqual(resp, model);
- }
- })
- });
- new Collection().fetch();
- this.ajaxSettings.success([model]);
- });
-
- QUnit.test("`sort` shouldn't always fire on `add`", function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection([{id: 1}, {id: 2}, {id: 3}], {
- comparator: 'id'
- });
- collection.sort = function(){ assert.ok(true); };
- collection.add([]);
- collection.add({id: 1});
- collection.add([{id: 2}, {id: 3}]);
- collection.add({id: 4});
- });
-
- QUnit.test('#1407 parse option on constructor parses collection and models', function(assert) {
- assert.expect(2);
- var model = {
- namespace: [{id: 1}, {id: 2}]
- };
- var Collection = Backbone.Collection.extend({
- model: Backbone.Model.extend({
- parse: function(m) {
- m.name = 'test';
- return m;
- }
- }),
- parse: function(m) {
- return m.namespace;
- }
- });
- var collection = new Collection(model, {parse: true});
-
- assert.equal(collection.length, 2);
- assert.equal(collection.at(0).get('name'), 'test');
- });
-
- QUnit.test('#1407 parse option on reset parses collection and models', function(assert) {
- assert.expect(2);
- var model = {
- namespace: [{id: 1}, {id: 2}]
- };
- var Collection = Backbone.Collection.extend({
- model: Backbone.Model.extend({
- parse: function(m) {
- m.name = 'test';
- return m;
- }
- }),
- parse: function(m) {
- return m.namespace;
- }
- });
- var collection = new Collection();
- collection.reset(model, {parse: true});
-
- assert.equal(collection.length, 2);
- assert.equal(collection.at(0).get('name'), 'test');
- });
-
-
- QUnit.test('Reset includes previous models in triggered event.', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model();
- var collection = new Backbone.Collection([model]);
- collection.on('reset', function(coll, options) {
- assert.deepEqual(options.previousModels, [model]);
- });
- collection.reset([]);
- });
-
- QUnit.test('set', function(assert) {
- var m1 = new Backbone.Model();
- var m2 = new Backbone.Model({id: 2});
- var m3 = new Backbone.Model();
- var collection = new Backbone.Collection([m1, m2]);
-
- // Test add/change/remove events
- collection.on('add', function(model) {
- assert.strictEqual(model, m3);
- });
- collection.on('change', function(model) {
- assert.strictEqual(model, m2);
- });
- collection.on('remove', function(model) {
- assert.strictEqual(model, m1);
- });
-
- // remove: false doesn't remove any models
- collection.set([], {remove: false});
- assert.strictEqual(collection.length, 2);
-
- // add: false doesn't add any models
- collection.set([m1, m2, m3], {add: false});
- assert.strictEqual(collection.length, 2);
-
- // merge: false doesn't change any models
- collection.set([m1, {id: 2, a: 1}], {merge: false});
- assert.strictEqual(m2.get('a'), void 0);
-
- // add: false, remove: false only merges existing models
- collection.set([m1, {id: 2, a: 0}, m3, {id: 4}], {add: false, remove: false});
- assert.strictEqual(collection.length, 2);
- assert.strictEqual(m2.get('a'), 0);
-
- // default options add/remove/merge as appropriate
- collection.set([{id: 2, a: 1}, m3]);
- assert.strictEqual(collection.length, 2);
- assert.strictEqual(m2.get('a'), 1);
-
- // Test removing models not passing an argument
- collection.off('remove').on('remove', function(model) {
- assert.ok(model === m2 || model === m3);
- });
- collection.set([]);
- assert.strictEqual(collection.length, 0);
-
- // Test null models on set doesn't clear collection
- collection.off();
- collection.set([{id: 1}]);
- collection.set();
- assert.strictEqual(collection.length, 1);
- });
-
- QUnit.test('set with only cids', function(assert) {
- assert.expect(3);
- var m1 = new Backbone.Model;
- var m2 = new Backbone.Model;
- var collection = new Backbone.Collection;
- collection.set([m1, m2]);
- assert.equal(collection.length, 2);
- collection.set([m1]);
- assert.equal(collection.length, 1);
- collection.set([m1, m1, m1, m2, m2], {remove: false});
- assert.equal(collection.length, 2);
- });
-
- QUnit.test('set with only idAttribute', function(assert) {
- assert.expect(3);
- var m1 = {_id: 1};
- var m2 = {_id: 2};
- var Col = Backbone.Collection.extend({
- model: Backbone.Model.extend({
- idAttribute: '_id'
- })
- });
- var collection = new Col;
- collection.set([m1, m2]);
- assert.equal(collection.length, 2);
- collection.set([m1]);
- assert.equal(collection.length, 1);
- collection.set([m1, m1, m1, m2, m2], {remove: false});
- assert.equal(collection.length, 2);
- });
-
- QUnit.test('set + merge with default values defined', function(assert) {
- var Model = Backbone.Model.extend({
- defaults: {
- key: 'value'
- }
- });
- var m = new Model({id: 1});
- var collection = new Backbone.Collection([m], {model: Model});
- assert.equal(collection.first().get('key'), 'value');
-
- collection.set({id: 1, key: 'other'});
- assert.equal(collection.first().get('key'), 'other');
-
- collection.set({id: 1, other: 'value'});
- assert.equal(collection.first().get('key'), 'other');
- assert.equal(collection.length, 1);
- });
-
- QUnit.test('merge without mutation', function(assert) {
- var Model = Backbone.Model.extend({
- initialize: function(attrs, options) {
- if (attrs.child) {
- this.set('child', new Model(attrs.child, options), options);
- }
- }
- });
- var Collection = Backbone.Collection.extend({model: Model});
- var data = [{id: 1, child: {id: 2}}];
- var collection = new Collection(data);
- assert.equal(collection.first().id, 1);
- collection.set(data);
- assert.equal(collection.first().id, 1);
- collection.set([{id: 2, child: {id: 2}}].concat(data));
- assert.deepEqual(collection.pluck('id'), [2, 1]);
- });
-
- QUnit.test('`set` and model level `parse`', function(assert) {
- var Model = Backbone.Model.extend({});
- var Collection = Backbone.Collection.extend({
- model: Model,
- parse: function(res) { return _.map(res.models, 'model'); }
- });
- var model = new Model({id: 1});
- var collection = new Collection(model);
- collection.set({models: [
- {model: {id: 1}},
- {model: {id: 2}}
- ]}, {parse: true});
- assert.equal(collection.first(), model);
- });
-
- QUnit.test('`set` data is only parsed once', function(assert) {
- var collection = new Backbone.Collection();
- collection.model = Backbone.Model.extend({
- parse: function(data) {
- assert.equal(data.parsed, void 0);
- data.parsed = true;
- return data;
- }
- });
- collection.set({}, {parse: true});
- });
-
- QUnit.test('`set` matches input order in the absence of a comparator', function(assert) {
- var one = new Backbone.Model({id: 1});
- var two = new Backbone.Model({id: 2});
- var three = new Backbone.Model({id: 3});
- var collection = new Backbone.Collection([one, two, three]);
- collection.set([{id: 3}, {id: 2}, {id: 1}]);
- assert.deepEqual(collection.models, [three, two, one]);
- collection.set([{id: 1}, {id: 2}]);
- assert.deepEqual(collection.models, [one, two]);
- collection.set([two, three, one]);
- assert.deepEqual(collection.models, [two, three, one]);
- collection.set([{id: 1}, {id: 2}], {remove: false});
- assert.deepEqual(collection.models, [two, three, one]);
- collection.set([{id: 1}, {id: 2}, {id: 3}], {merge: false});
- assert.deepEqual(collection.models, [one, two, three]);
- collection.set([three, two, one, {id: 4}], {add: false});
- assert.deepEqual(collection.models, [one, two, three]);
- });
-
- QUnit.test('#1894 - Push should not trigger a sort', function(assert) {
- assert.expect(0);
- var Collection = Backbone.Collection.extend({
- comparator: 'id',
- sort: function() { assert.ok(false); }
- });
- new Collection().push({id: 1});
- });
-
- QUnit.test('#2428 - push duplicate models, return the correct one', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection;
- var model1 = collection.push({id: 101});
- var model2 = collection.push({id: 101});
- assert.ok(model2.cid === model1.cid);
- });
-
- QUnit.test('`set` with non-normal id', function(assert) {
- var Collection = Backbone.Collection.extend({
- model: Backbone.Model.extend({idAttribute: '_id'})
- });
- var collection = new Collection({_id: 1});
- collection.set([{_id: 1, a: 1}], {add: false});
- assert.equal(collection.first().get('a'), 1);
- });
-
- QUnit.test('#1894 - `sort` can optionally be turned off', function(assert) {
- assert.expect(0);
- var Collection = Backbone.Collection.extend({
- comparator: 'id',
- sort: function() { assert.ok(false); }
- });
- new Collection().add({id: 1}, {sort: false});
- });
-
- QUnit.test('#1915 - `parse` data in the right order in `set`', function(assert) {
- var collection = new (Backbone.Collection.extend({
- parse: function(data) {
- assert.strictEqual(data.status, 'ok');
- return data.data;
- }
- }));
- var res = {status: 'ok', data: [{id: 1}]};
- collection.set(res, {parse: true});
- });
-
- QUnit.test('#1939 - `parse` is passed `options`', function(assert) {
- var done = assert.async();
- assert.expect(1);
- var collection = new (Backbone.Collection.extend({
- url: '/',
- parse: function(data, options) {
- assert.strictEqual(options.xhr.someHeader, 'headerValue');
- return data;
- }
- }));
- var ajax = Backbone.ajax;
- Backbone.ajax = function(params) {
- _.defer(params.success, []);
- return {someHeader: 'headerValue'};
- };
- collection.fetch({
- success: function() { done(); }
- });
- Backbone.ajax = ajax;
- });
-
- QUnit.test('fetch will pass extra options to success callback', function(assert) {
- assert.expect(1);
- var SpecialSyncCollection = Backbone.Collection.extend({
- url: '/test',
- sync: function(method, collection, options) {
- _.extend(options, {specialSync: true});
- return Backbone.Collection.prototype.sync.call(this, method, collection, options);
- }
- });
-
- var collection = new SpecialSyncCollection();
-
- var onSuccess = function(coll, resp, options) {
- assert.ok(options.specialSync, 'Options were passed correctly to callback');
- };
-
- collection.fetch({success: onSuccess});
- this.ajaxSettings.success();
- });
-
- QUnit.test('`add` only `sort`s when necessary', function(assert) {
- assert.expect(2);
- var collection = new (Backbone.Collection.extend({
- comparator: 'a'
- }))([{id: 1}, {id: 2}, {id: 3}]);
- collection.on('sort', function() { assert.ok(true); });
- collection.add({id: 4}); // do sort, new model
- collection.add({id: 1, a: 1}, {merge: true}); // do sort, comparator change
- collection.add({id: 1, b: 1}, {merge: true}); // don't sort, no comparator change
- collection.add({id: 1, a: 1}, {merge: true}); // don't sort, no comparator change
- collection.add(collection.models); // don't sort, nothing new
- collection.add(collection.models, {merge: true}); // don't sort
- });
-
- QUnit.test('`add` only `sort`s when necessary with comparator function', function(assert) {
- assert.expect(3);
- var collection = new (Backbone.Collection.extend({
- comparator: function(m1, m2) {
- return m1.get('a') > m2.get('a') ? 1 : (m1.get('a') < m2.get('a') ? -1 : 0);
- }
- }))([{id: 1}, {id: 2}, {id: 3}]);
- collection.on('sort', function() { assert.ok(true); });
- collection.add({id: 4}); // do sort, new model
- collection.add({id: 1, a: 1}, {merge: true}); // do sort, model change
- collection.add({id: 1, b: 1}, {merge: true}); // do sort, model change
- collection.add({id: 1, a: 1}, {merge: true}); // don't sort, no model change
- collection.add(collection.models); // don't sort, nothing new
- collection.add(collection.models, {merge: true}); // don't sort
- });
-
- QUnit.test('Attach options to collection.', function(assert) {
- assert.expect(2);
- var Model = Backbone.Model;
- var comparator = function(){};
-
- var collection = new Backbone.Collection([], {
- model: Model,
- comparator: comparator
- });
-
- assert.ok(collection.model === Model);
- assert.ok(collection.comparator === comparator);
- });
-
- QUnit.test('Pass falsey for `models` for empty Col with `options`', function(assert) {
- assert.expect(9);
- var opts = {a: 1, b: 2};
- _.forEach([undefined, null, false], function(falsey) {
- var Collection = Backbone.Collection.extend({
- initialize: function(models, options) {
- assert.strictEqual(models, falsey);
- assert.strictEqual(options, opts);
- }
- });
-
- var collection = new Collection(falsey, opts);
- assert.strictEqual(collection.length, 0);
- });
- });
-
- QUnit.test('`add` overrides `set` flags', function(assert) {
- var collection = new Backbone.Collection();
- collection.once('add', function(model, coll, options) {
- coll.add({id: 2}, options);
- });
- collection.set({id: 1});
- assert.equal(collection.length, 2);
- });
-
- QUnit.test('#2606 - Collection#create, success arguments', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection;
- collection.url = 'test';
- collection.create({}, {
- success: function(model, resp, options) {
- assert.strictEqual(resp, 'response');
- }
- });
- this.ajaxSettings.success('response');
- });
-
- QUnit.test('#2612 - nested `parse` works with `Collection#set`', function(assert) {
-
- var Job = Backbone.Model.extend({
- constructor: function() {
- this.items = new Items();
- Backbone.Model.apply(this, arguments);
- },
- parse: function(attrs) {
- this.items.set(attrs.items, {parse: true});
- return _.omit(attrs, 'items');
- }
- });
-
- var Item = Backbone.Model.extend({
- constructor: function() {
- this.subItems = new Backbone.Collection();
- Backbone.Model.apply(this, arguments);
- },
- parse: function(attrs) {
- this.subItems.set(attrs.subItems, {parse: true});
- return _.omit(attrs, 'subItems');
- }
- });
-
- var Items = Backbone.Collection.extend({
- model: Item
- });
-
- var data = {
- name: 'JobName',
- id: 1,
- items: [{
- id: 1,
- name: 'Sub1',
- subItems: [
- {id: 1, subName: 'One'},
- {id: 2, subName: 'Two'}
- ]
- }, {
- id: 2,
- name: 'Sub2',
- subItems: [
- {id: 3, subName: 'Three'},
- {id: 4, subName: 'Four'}
- ]
- }]
- };
-
- var newData = {
- name: 'NewJobName',
- id: 1,
- items: [{
- id: 1,
- name: 'NewSub1',
- subItems: [
- {id: 1, subName: 'NewOne'},
- {id: 2, subName: 'NewTwo'}
- ]
- }, {
- id: 2,
- name: 'NewSub2',
- subItems: [
- {id: 3, subName: 'NewThree'},
- {id: 4, subName: 'NewFour'}
- ]
- }]
- };
-
- var job = new Job(data, {parse: true});
- assert.equal(job.get('name'), 'JobName');
- assert.equal(job.items.at(0).get('name'), 'Sub1');
- assert.equal(job.items.length, 2);
- assert.equal(job.items.get(1).subItems.get(1).get('subName'), 'One');
- assert.equal(job.items.get(2).subItems.get(3).get('subName'), 'Three');
- job.set(job.parse(newData, {parse: true}));
- assert.equal(job.get('name'), 'NewJobName');
- assert.equal(job.items.at(0).get('name'), 'NewSub1');
- assert.equal(job.items.length, 2);
- assert.equal(job.items.get(1).subItems.get(1).get('subName'), 'NewOne');
- assert.equal(job.items.get(2).subItems.get(3).get('subName'), 'NewThree');
- });
-
- QUnit.test('_addReference binds all collection events & adds to the lookup hashes', function(assert) {
- assert.expect(8);
-
- var calls = {add: 0, remove: 0};
-
- var Collection = Backbone.Collection.extend({
-
- _addReference: function(model) {
- Backbone.Collection.prototype._addReference.apply(this, arguments);
- calls.add++;
- assert.equal(model, this._byId[model.id]);
- assert.equal(model, this._byId[model.cid]);
- assert.equal(model._events.all.length, 1);
- },
-
- _removeReference: function(model) {
- Backbone.Collection.prototype._removeReference.apply(this, arguments);
- calls.remove++;
- assert.equal(this._byId[model.id], void 0);
- assert.equal(this._byId[model.cid], void 0);
- assert.equal(model.collection, void 0);
- }
-
- });
-
- var collection = new Collection();
- var model = collection.add({id: 1});
- collection.remove(model);
-
- assert.equal(calls.add, 1);
- assert.equal(calls.remove, 1);
- });
-
- QUnit.test('Do not allow duplicate models to be `add`ed or `set`', function(assert) {
- var collection = new Backbone.Collection();
-
- collection.add([{id: 1}, {id: 1}]);
- assert.equal(collection.length, 1);
- assert.equal(collection.models.length, 1);
-
- collection.set([{id: 1}, {id: 1}]);
- assert.equal(collection.length, 1);
- assert.equal(collection.models.length, 1);
- });
-
- QUnit.test('#3020: #set with {add: false} should not throw.', function(assert) {
- assert.expect(2);
- var collection = new Backbone.Collection;
- collection.set([{id: 1}], {add: false});
- assert.strictEqual(collection.length, 0);
- assert.strictEqual(collection.models.length, 0);
- });
-
- QUnit.test('create with wait, model instance, #3028', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection();
- var model = new Backbone.Model({id: 1});
- model.sync = function(){
- assert.equal(this.collection, collection);
- };
- collection.create(model, {wait: true});
- });
-
- QUnit.test('modelId', function(assert) {
- var Stooge = Backbone.Model.extend();
- var StoogeCollection = Backbone.Collection.extend({model: Stooge});
-
- // Default to using `Collection::model::idAttribute`.
- assert.equal(StoogeCollection.prototype.modelId({id: 1}), 1);
- Stooge.prototype.idAttribute = '_id';
- assert.equal(StoogeCollection.prototype.modelId({_id: 1}), 1);
- });
-
- QUnit.test('Polymorphic models work with "simple" constructors', function(assert) {
- var A = Backbone.Model.extend();
- var B = Backbone.Model.extend();
- var C = Backbone.Collection.extend({
- model: function(attrs) {
- return attrs.type === 'a' ? new A(attrs) : new B(attrs);
- }
- });
- var collection = new C([{id: 1, type: 'a'}, {id: 2, type: 'b'}]);
- assert.equal(collection.length, 2);
- assert.ok(collection.at(0) instanceof A);
- assert.equal(collection.at(0).id, 1);
- assert.ok(collection.at(1) instanceof B);
- assert.equal(collection.at(1).id, 2);
- });
-
- QUnit.test('Polymorphic models work with "advanced" constructors', function(assert) {
- var A = Backbone.Model.extend({idAttribute: '_id'});
- var B = Backbone.Model.extend({idAttribute: '_id'});
- var C = Backbone.Collection.extend({
- model: Backbone.Model.extend({
- constructor: function(attrs) {
- return attrs.type === 'a' ? new A(attrs) : new B(attrs);
- },
-
- idAttribute: '_id'
- })
- });
- var collection = new C([{_id: 1, type: 'a'}, {_id: 2, type: 'b'}]);
- assert.equal(collection.length, 2);
- assert.ok(collection.at(0) instanceof A);
- assert.equal(collection.at(0), collection.get(1));
- assert.ok(collection.at(1) instanceof B);
- assert.equal(collection.at(1), collection.get(2));
-
- C = Backbone.Collection.extend({
- model: function(attrs) {
- return attrs.type === 'a' ? new A(attrs) : new B(attrs);
- },
-
- modelId: function(attrs) {
- return attrs.type + '-' + attrs.id;
- }
- });
- collection = new C([{id: 1, type: 'a'}, {id: 1, type: 'b'}]);
- assert.equal(collection.length, 2);
- assert.ok(collection.at(0) instanceof A);
- assert.equal(collection.at(0), collection.get('a-1'));
- assert.ok(collection.at(1) instanceof B);
- assert.equal(collection.at(1), collection.get('b-1'));
- });
-
- QUnit.test('Collection with polymorphic models receives default id from modelId', function(assert) {
- assert.expect(6);
- // When the polymorphic models use 'id' for the idAttribute, all is fine.
- var C1 = Backbone.Collection.extend({
- model: function(attrs) {
- return new Backbone.Model(attrs);
- }
- });
- var c1 = new C1({id: 1});
- assert.equal(c1.get(1).id, 1);
- assert.equal(c1.modelId({id: 1}), 1);
-
- // If the polymorphic models define their own idAttribute,
- // the modelId method should be overridden, for the reason below.
- var M = Backbone.Model.extend({
- idAttribute: '_id'
- });
- var C2 = Backbone.Collection.extend({
- model: function(attrs) {
- return new M(attrs);
- }
- });
- var c2 = new C2({'_id': 1});
- assert.equal(c2.get(1), void 0);
- assert.equal(c2.modelId(c2.at(0).attributes), void 0);
- var m = new M({'_id': 2});
- c2.add(m);
- assert.equal(c2.get(2), void 0);
- assert.equal(c2.modelId(m.attributes), void 0);
- });
-
- QUnit.test('#3039 #3951: adding at index fires with correct at', function(assert) {
- assert.expect(4);
- var collection = new Backbone.Collection([{val: 0}, {val: 4}]);
- collection.on('add', function(model, coll, options) {
- assert.equal(model.get('val'), options.index);
- });
- collection.add([{val: 1}, {val: 2}, {val: 3}], {at: 1});
- collection.add({val: 5}, {at: 10});
- });
-
- QUnit.test('#3039: index is not sent when at is not specified', function(assert) {
- assert.expect(2);
- var collection = new Backbone.Collection([{at: 0}]);
- collection.on('add', function(model, coll, options) {
- assert.equal(undefined, options.index);
- });
- collection.add([{at: 1}, {at: 2}]);
- });
-
- QUnit.test('#3199 - Order changing should trigger a sort', function(assert) {
- assert.expect(1);
- var one = new Backbone.Model({id: 1});
- var two = new Backbone.Model({id: 2});
- var three = new Backbone.Model({id: 3});
- var collection = new Backbone.Collection([one, two, three]);
- collection.on('sort', function() {
- assert.ok(true);
- });
- collection.set([{id: 3}, {id: 2}, {id: 1}]);
- });
-
- QUnit.test('#3199 - Adding a model should trigger a sort', function(assert) {
- assert.expect(1);
- var one = new Backbone.Model({id: 1});
- var two = new Backbone.Model({id: 2});
- var three = new Backbone.Model({id: 3});
- var collection = new Backbone.Collection([one, two, three]);
- collection.on('sort', function() {
- assert.ok(true);
- });
- collection.set([{id: 1}, {id: 2}, {id: 3}, {id: 0}]);
- });
-
- QUnit.test('#3199 - Order not changing should not trigger a sort', function(assert) {
- assert.expect(0);
- var one = new Backbone.Model({id: 1});
- var two = new Backbone.Model({id: 2});
- var three = new Backbone.Model({id: 3});
- var collection = new Backbone.Collection([one, two, three]);
- collection.on('sort', function() {
- assert.ok(false);
- });
- collection.set([{id: 1}, {id: 2}, {id: 3}]);
- });
-
- QUnit.test('add supports negative indexes', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection([{id: 1}]);
- collection.add([{id: 2}, {id: 3}], {at: -1});
- collection.add([{id: 2.5}], {at: -2});
- collection.add([{id: 0.5}], {at: -6});
- assert.equal(collection.pluck('id').join(','), '0.5,1,2,2.5,3');
- });
-
- QUnit.test('#set accepts options.at as a string', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection([{id: 1}, {id: 2}]);
- collection.add([{id: 3}], {at: '1'});
- assert.deepEqual(collection.pluck('id'), [1, 3, 2]);
- });
-
- QUnit.test('adding multiple models triggers `update` event once', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection;
- collection.on('update', function() { assert.ok(true); });
- collection.add([{id: 1}, {id: 2}, {id: 3}]);
- });
-
- QUnit.test('removing models triggers `update` event once', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection([{id: 1}, {id: 2}, {id: 3}]);
- collection.on('update', function() { assert.ok(true); });
- collection.remove([{id: 1}, {id: 2}]);
- });
-
- QUnit.test('remove does not trigger `update` when nothing removed', function(assert) {
- assert.expect(0);
- var collection = new Backbone.Collection([{id: 1}, {id: 2}]);
- collection.on('update', function() { assert.ok(false); });
- collection.remove([{id: 3}]);
- });
-
- QUnit.test('set triggers `set` event once', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection([{id: 1}, {id: 2}]);
- collection.on('update', function() { assert.ok(true); });
- collection.set([{id: 1}, {id: 3}]);
- });
-
- QUnit.test('set does not trigger `update` event when nothing added nor removed', function(assert) {
- var collection = new Backbone.Collection([{id: 1}, {id: 2}]);
- collection.on('update', function(coll, options) {
- assert.equal(options.changes.added.length, 0);
- assert.equal(options.changes.removed.length, 0);
- assert.equal(options.changes.merged.length, 2);
- });
- collection.set([{id: 1}, {id: 2}]);
- });
-
- QUnit.test('#3610 - invoke collects arguments', function(assert) {
- assert.expect(3);
- var Model = Backbone.Model.extend({
- method: function(x, y, z) {
- assert.equal(x, 1);
- assert.equal(y, 2);
- assert.equal(z, 3);
- }
- });
- var Collection = Backbone.Collection.extend({
- model: Model
- });
- var collection = new Collection([{id: 1}]);
- collection.invoke('method', 1, 2, 3);
- });
-
- QUnit.test('#3662 - triggering change without model will not error', function(assert) {
- assert.expect(1);
- var collection = new Backbone.Collection([{id: 1}]);
- var model = collection.first();
- collection.on('change', function(m) {
- assert.equal(m, undefined);
- });
- model.trigger('change');
- });
-
- QUnit.test('#3871 - falsy parse result creates empty collection', function(assert) {
- var collection = new (Backbone.Collection.extend({
- parse: function(data, options) {}
- }));
- collection.set('', {parse: true});
- assert.equal(collection.length, 0);
- });
-
- QUnit.test("#3711 - remove's `update` event returns one removed model", function(assert) {
- var model = new Backbone.Model({id: 1, title: 'First Post'});
- var collection = new Backbone.Collection([model]);
- collection.on('update', function(context, options) {
- var changed = options.changes;
- assert.deepEqual(changed.added, []);
- assert.deepEqual(changed.merged, []);
- assert.strictEqual(changed.removed[0], model);
- });
- collection.remove(model);
- });
-
- QUnit.test("#3711 - remove's `update` event returns multiple removed models", function(assert) {
- var model = new Backbone.Model({id: 1, title: 'First Post'});
- var model2 = new Backbone.Model({id: 2, title: 'Second Post'});
- var collection = new Backbone.Collection([model, model2]);
- collection.on('update', function(context, options) {
- var changed = options.changes;
- assert.deepEqual(changed.added, []);
- assert.deepEqual(changed.merged, []);
- assert.ok(changed.removed.length === 2);
-
- assert.ok(_.indexOf(changed.removed, model) > -1 && _.indexOf(changed.removed, model2) > -1);
- });
- collection.remove([model, model2]);
- });
-
- QUnit.test("#3711 - set's `update` event returns one added model", function(assert) {
- var model = new Backbone.Model({id: 1, title: 'First Post'});
- var collection = new Backbone.Collection();
- collection.on('update', function(context, options) {
- var addedModels = options.changes.added;
- assert.ok(addedModels.length === 1);
- assert.strictEqual(addedModels[0], model);
- });
- collection.set(model);
- });
-
- QUnit.test("#3711 - set's `update` event returns multiple added models", function(assert) {
- var model = new Backbone.Model({id: 1, title: 'First Post'});
- var model2 = new Backbone.Model({id: 2, title: 'Second Post'});
- var collection = new Backbone.Collection();
- collection.on('update', function(context, options) {
- var addedModels = options.changes.added;
- assert.ok(addedModels.length === 2);
- assert.strictEqual(addedModels[0], model);
- assert.strictEqual(addedModels[1], model2);
- });
- collection.set([model, model2]);
- });
-
- QUnit.test("#3711 - set's `update` event returns one removed model", function(assert) {
- var model = new Backbone.Model({id: 1, title: 'First Post'});
- var model2 = new Backbone.Model({id: 2, title: 'Second Post'});
- var model3 = new Backbone.Model({id: 3, title: 'My Last Post'});
- var collection = new Backbone.Collection([model]);
- collection.on('update', function(context, options) {
- var changed = options.changes;
- assert.equal(changed.added.length, 2);
- assert.equal(changed.merged.length, 0);
- assert.ok(changed.removed.length === 1);
- assert.strictEqual(changed.removed[0], model);
- });
- collection.set([model2, model3]);
- });
-
- QUnit.test("#3711 - set's `update` event returns multiple removed models", function(assert) {
- var model = new Backbone.Model({id: 1, title: 'First Post'});
- var model2 = new Backbone.Model({id: 2, title: 'Second Post'});
- var model3 = new Backbone.Model({id: 3, title: 'My Last Post'});
- var collection = new Backbone.Collection([model, model2]);
- collection.on('update', function(context, options) {
- var removedModels = options.changes.removed;
- assert.ok(removedModels.length === 2);
- assert.strictEqual(removedModels[0], model);
- assert.strictEqual(removedModels[1], model2);
- });
- collection.set([model3]);
- });
-
- QUnit.test("#3711 - set's `update` event returns one merged model", function(assert) {
- var model = new Backbone.Model({id: 1, title: 'First Post'});
- var model2 = new Backbone.Model({id: 2, title: 'Second Post'});
- var model2Update = new Backbone.Model({id: 2, title: 'Second Post V2'});
- var collection = new Backbone.Collection([model, model2]);
- collection.on('update', function(context, options) {
- var mergedModels = options.changes.merged;
- assert.ok(mergedModels.length === 1);
- assert.strictEqual(mergedModels[0].get('title'), model2Update.get('title'));
- });
- collection.set([model2Update]);
- });
-
- QUnit.test("#3711 - set's `update` event returns multiple merged models", function(assert) {
- var model = new Backbone.Model({id: 1, title: 'First Post'});
- var modelUpdate = new Backbone.Model({id: 1, title: 'First Post V2'});
- var model2 = new Backbone.Model({id: 2, title: 'Second Post'});
- var model2Update = new Backbone.Model({id: 2, title: 'Second Post V2'});
- var collection = new Backbone.Collection([model, model2]);
- collection.on('update', function(context, options) {
- var mergedModels = options.changes.merged;
- assert.ok(mergedModels.length === 2);
- assert.strictEqual(mergedModels[0].get('title'), model2Update.get('title'));
- assert.strictEqual(mergedModels[1].get('title'), modelUpdate.get('title'));
- });
- collection.set([model2Update, modelUpdate]);
- });
-
- QUnit.test("#3711 - set's `update` event should not be triggered adding a model which already exists exactly alike", function(assert) {
- var fired = false;
- var model = new Backbone.Model({id: 1, title: 'First Post'});
- var collection = new Backbone.Collection([model]);
- collection.on('update', function(context, options) {
- fired = true;
- });
- collection.set([model]);
- assert.equal(fired, false);
- });
-
-})();
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/events.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/events.js
deleted file mode 100644
index 544b39a1..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/events.js
+++ /dev/null
@@ -1,706 +0,0 @@
-(function() {
-
- QUnit.module('Backbone.Events');
-
- QUnit.test('on and trigger', function(assert) {
- assert.expect(2);
- var obj = {counter: 0};
- _.extend(obj, Backbone.Events);
- obj.on('event', function() { obj.counter += 1; });
- obj.trigger('event');
- assert.equal(obj.counter, 1, 'counter should be incremented.');
- obj.trigger('event');
- obj.trigger('event');
- obj.trigger('event');
- obj.trigger('event');
- assert.equal(obj.counter, 5, 'counter should be incremented five times.');
- });
-
- QUnit.test('binding and triggering multiple events', function(assert) {
- assert.expect(4);
- var obj = {counter: 0};
- _.extend(obj, Backbone.Events);
-
- obj.on('a b c', function() { obj.counter += 1; });
-
- obj.trigger('a');
- assert.equal(obj.counter, 1);
-
- obj.trigger('a b');
- assert.equal(obj.counter, 3);
-
- obj.trigger('c');
- assert.equal(obj.counter, 4);
-
- obj.off('a c');
- obj.trigger('a b c');
- assert.equal(obj.counter, 5);
- });
-
- QUnit.test('binding and triggering with event maps', function(assert) {
- var obj = {counter: 0};
- _.extend(obj, Backbone.Events);
-
- var increment = function() {
- this.counter += 1;
- };
-
- obj.on({
- a: increment,
- b: increment,
- c: increment
- }, obj);
-
- obj.trigger('a');
- assert.equal(obj.counter, 1);
-
- obj.trigger('a b');
- assert.equal(obj.counter, 3);
-
- obj.trigger('c');
- assert.equal(obj.counter, 4);
-
- obj.off({
- a: increment,
- c: increment
- }, obj);
- obj.trigger('a b c');
- assert.equal(obj.counter, 5);
- });
-
- QUnit.test('binding and triggering multiple event names with event maps', function(assert) {
- var obj = {counter: 0};
- _.extend(obj, Backbone.Events);
-
- var increment = function() {
- this.counter += 1;
- };
-
- obj.on({
- 'a b c': increment
- });
-
- obj.trigger('a');
- assert.equal(obj.counter, 1);
-
- obj.trigger('a b');
- assert.equal(obj.counter, 3);
-
- obj.trigger('c');
- assert.equal(obj.counter, 4);
-
- obj.off({
- 'a c': increment
- });
- obj.trigger('a b c');
- assert.equal(obj.counter, 5);
- });
-
- QUnit.test('binding and trigger with event maps context', function(assert) {
- assert.expect(2);
- var obj = {counter: 0};
- var context = {};
- _.extend(obj, Backbone.Events);
-
- obj.on({
- a: function() {
- assert.strictEqual(this, context, 'defaults `context` to `callback` param');
- }
- }, context).trigger('a');
-
- obj.off().on({
- a: function() {
- assert.strictEqual(this, context, 'will not override explicit `context` param');
- }
- }, this, context).trigger('a');
- });
-
- QUnit.test('listenTo and stopListening', function(assert) {
- assert.expect(1);
- var a = _.extend({}, Backbone.Events);
- var b = _.extend({}, Backbone.Events);
- a.listenTo(b, 'all', function(){ assert.ok(true); });
- b.trigger('anything');
- a.listenTo(b, 'all', function(){ assert.ok(false); });
- a.stopListening();
- b.trigger('anything');
- });
-
- QUnit.test('listenTo and stopListening with event maps', function(assert) {
- assert.expect(4);
- var a = _.extend({}, Backbone.Events);
- var b = _.extend({}, Backbone.Events);
- var cb = function(){ assert.ok(true); };
- a.listenTo(b, {event: cb});
- b.trigger('event');
- a.listenTo(b, {event2: cb});
- b.on('event2', cb);
- a.stopListening(b, {event2: cb});
- b.trigger('event event2');
- a.stopListening();
- b.trigger('event event2');
- });
-
- QUnit.test('stopListening with omitted args', function(assert) {
- assert.expect(2);
- var a = _.extend({}, Backbone.Events);
- var b = _.extend({}, Backbone.Events);
- var cb = function() { assert.ok(true); };
- a.listenTo(b, 'event', cb);
- b.on('event', cb);
- a.listenTo(b, 'event2', cb);
- a.stopListening(null, {event: cb});
- b.trigger('event event2');
- b.off();
- a.listenTo(b, 'event event2', cb);
- a.stopListening(null, 'event');
- a.stopListening();
- b.trigger('event2');
- });
-
- QUnit.test('listenToOnce', function(assert) {
- assert.expect(2);
- // Same as the previous test, but we use once rather than having to explicitly unbind
- var obj = {counterA: 0, counterB: 0};
- _.extend(obj, Backbone.Events);
- var incrA = function(){ obj.counterA += 1; obj.trigger('event'); };
- var incrB = function(){ obj.counterB += 1; };
- obj.listenToOnce(obj, 'event', incrA);
- obj.listenToOnce(obj, 'event', incrB);
- obj.trigger('event');
- assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');
- assert.equal(obj.counterB, 1, 'counterB should have only been incremented once.');
- });
-
- QUnit.test('listenToOnce and stopListening', function(assert) {
- assert.expect(1);
- var a = _.extend({}, Backbone.Events);
- var b = _.extend({}, Backbone.Events);
- a.listenToOnce(b, 'all', function() { assert.ok(true); });
- b.trigger('anything');
- b.trigger('anything');
- a.listenToOnce(b, 'all', function() { assert.ok(false); });
- a.stopListening();
- b.trigger('anything');
- });
-
- QUnit.test('listenTo, listenToOnce and stopListening', function(assert) {
- assert.expect(1);
- var a = _.extend({}, Backbone.Events);
- var b = _.extend({}, Backbone.Events);
- a.listenToOnce(b, 'all', function() { assert.ok(true); });
- b.trigger('anything');
- b.trigger('anything');
- a.listenTo(b, 'all', function() { assert.ok(false); });
- a.stopListening();
- b.trigger('anything');
- });
-
- QUnit.test('listenTo and stopListening with event maps', function(assert) {
- assert.expect(1);
- var a = _.extend({}, Backbone.Events);
- var b = _.extend({}, Backbone.Events);
- a.listenTo(b, {change: function(){ assert.ok(true); }});
- b.trigger('change');
- a.listenTo(b, {change: function(){ assert.ok(false); }});
- a.stopListening();
- b.trigger('change');
- });
-
- QUnit.test('listenTo yourself', function(assert) {
- assert.expect(1);
- var e = _.extend({}, Backbone.Events);
- e.listenTo(e, 'foo', function(){ assert.ok(true); });
- e.trigger('foo');
- });
-
- QUnit.test('listenTo yourself cleans yourself up with stopListening', function(assert) {
- assert.expect(1);
- var e = _.extend({}, Backbone.Events);
- e.listenTo(e, 'foo', function(){ assert.ok(true); });
- e.trigger('foo');
- e.stopListening();
- e.trigger('foo');
- });
-
- QUnit.test('stopListening cleans up references', function(assert) {
- assert.expect(12);
- var a = _.extend({}, Backbone.Events);
- var b = _.extend({}, Backbone.Events);
- var fn = function() {};
- b.on('event', fn);
- a.listenTo(b, 'event', fn).stopListening();
- assert.equal(_.size(a._listeningTo), 0);
- assert.equal(_.size(b._events.event), 1);
- assert.equal(_.size(b._listeners), 0);
- a.listenTo(b, 'event', fn).stopListening(b);
- assert.equal(_.size(a._listeningTo), 0);
- assert.equal(_.size(b._events.event), 1);
- assert.equal(_.size(b._listeners), 0);
- a.listenTo(b, 'event', fn).stopListening(b, 'event');
- assert.equal(_.size(a._listeningTo), 0);
- assert.equal(_.size(b._events.event), 1);
- assert.equal(_.size(b._listeners), 0);
- a.listenTo(b, 'event', fn).stopListening(b, 'event', fn);
- assert.equal(_.size(a._listeningTo), 0);
- assert.equal(_.size(b._events.event), 1);
- assert.equal(_.size(b._listeners), 0);
- });
-
- QUnit.test('stopListening cleans up references from listenToOnce', function(assert) {
- assert.expect(12);
- var a = _.extend({}, Backbone.Events);
- var b = _.extend({}, Backbone.Events);
- var fn = function() {};
- b.on('event', fn);
- a.listenToOnce(b, 'event', fn).stopListening();
- assert.equal(_.size(a._listeningTo), 0);
- assert.equal(_.size(b._events.event), 1);
- assert.equal(_.size(b._listeners), 0);
- a.listenToOnce(b, 'event', fn).stopListening(b);
- assert.equal(_.size(a._listeningTo), 0);
- assert.equal(_.size(b._events.event), 1);
- assert.equal(_.size(b._listeners), 0);
- a.listenToOnce(b, 'event', fn).stopListening(b, 'event');
- assert.equal(_.size(a._listeningTo), 0);
- assert.equal(_.size(b._events.event), 1);
- assert.equal(_.size(b._listeners), 0);
- a.listenToOnce(b, 'event', fn).stopListening(b, 'event', fn);
- assert.equal(_.size(a._listeningTo), 0);
- assert.equal(_.size(b._events.event), 1);
- assert.equal(_.size(b._listeners), 0);
- });
-
- QUnit.test('listenTo and off cleaning up references', function(assert) {
- assert.expect(8);
- var a = _.extend({}, Backbone.Events);
- var b = _.extend({}, Backbone.Events);
- var fn = function() {};
- a.listenTo(b, 'event', fn);
- b.off();
- assert.equal(_.size(a._listeningTo), 0);
- assert.equal(_.size(b._listeners), 0);
- a.listenTo(b, 'event', fn);
- b.off('event');
- assert.equal(_.size(a._listeningTo), 0);
- assert.equal(_.size(b._listeners), 0);
- a.listenTo(b, 'event', fn);
- b.off(null, fn);
- assert.equal(_.size(a._listeningTo), 0);
- assert.equal(_.size(b._listeners), 0);
- a.listenTo(b, 'event', fn);
- b.off(null, null, a);
- assert.equal(_.size(a._listeningTo), 0);
- assert.equal(_.size(b._listeners), 0);
- });
-
- QUnit.test('listenTo and stopListening cleaning up references', function(assert) {
- assert.expect(2);
- var a = _.extend({}, Backbone.Events);
- var b = _.extend({}, Backbone.Events);
- a.listenTo(b, 'all', function(){ assert.ok(true); });
- b.trigger('anything');
- a.listenTo(b, 'other', function(){ assert.ok(false); });
- a.stopListening(b, 'other');
- a.stopListening(b, 'all');
- assert.equal(_.size(a._listeningTo), 0);
- });
-
- QUnit.test('listenToOnce without context cleans up references after the event has fired', function(assert) {
- assert.expect(2);
- var a = _.extend({}, Backbone.Events);
- var b = _.extend({}, Backbone.Events);
- a.listenToOnce(b, 'all', function(){ assert.ok(true); });
- b.trigger('anything');
- assert.equal(_.size(a._listeningTo), 0);
- });
-
- QUnit.test('listenToOnce with event maps cleans up references', function(assert) {
- assert.expect(2);
- var a = _.extend({}, Backbone.Events);
- var b = _.extend({}, Backbone.Events);
- a.listenToOnce(b, {
- one: function() { assert.ok(true); },
- two: function() { assert.ok(false); }
- });
- b.trigger('one');
- assert.equal(_.size(a._listeningTo), 1);
- });
-
- QUnit.test('listenToOnce with event maps binds the correct `this`', function(assert) {
- assert.expect(1);
- var a = _.extend({}, Backbone.Events);
- var b = _.extend({}, Backbone.Events);
- a.listenToOnce(b, {
- one: function() { assert.ok(this === a); },
- two: function() { assert.ok(false); }
- });
- b.trigger('one');
- });
-
- QUnit.test("listenTo with empty callback doesn't throw an error", function(assert) {
- assert.expect(1);
- var e = _.extend({}, Backbone.Events);
- e.listenTo(e, 'foo', null);
- e.trigger('foo');
- assert.ok(true);
- });
-
- QUnit.test('trigger all for each event', function(assert) {
- assert.expect(3);
- var a, b, obj = {counter: 0};
- _.extend(obj, Backbone.Events);
- obj.on('all', function(event) {
- obj.counter++;
- if (event === 'a') a = true;
- if (event === 'b') b = true;
- })
- .trigger('a b');
- assert.ok(a);
- assert.ok(b);
- assert.equal(obj.counter, 2);
- });
-
- QUnit.test('on, then unbind all functions', function(assert) {
- assert.expect(1);
- var obj = {counter: 0};
- _.extend(obj, Backbone.Events);
- var callback = function() { obj.counter += 1; };
- obj.on('event', callback);
- obj.trigger('event');
- obj.off('event');
- obj.trigger('event');
- assert.equal(obj.counter, 1, 'counter should have only been incremented once.');
- });
-
- QUnit.test('bind two callbacks, unbind only one', function(assert) {
- assert.expect(2);
- var obj = {counterA: 0, counterB: 0};
- _.extend(obj, Backbone.Events);
- var callback = function() { obj.counterA += 1; };
- obj.on('event', callback);
- obj.on('event', function() { obj.counterB += 1; });
- obj.trigger('event');
- obj.off('event', callback);
- obj.trigger('event');
- assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');
- assert.equal(obj.counterB, 2, 'counterB should have been incremented twice.');
- });
-
- QUnit.test('unbind a callback in the midst of it firing', function(assert) {
- assert.expect(1);
- var obj = {counter: 0};
- _.extend(obj, Backbone.Events);
- var callback = function() {
- obj.counter += 1;
- obj.off('event', callback);
- };
- obj.on('event', callback);
- obj.trigger('event');
- obj.trigger('event');
- obj.trigger('event');
- assert.equal(obj.counter, 1, 'the callback should have been unbound.');
- });
-
- QUnit.test('two binds that unbind themeselves', function(assert) {
- assert.expect(2);
- var obj = {counterA: 0, counterB: 0};
- _.extend(obj, Backbone.Events);
- var incrA = function(){ obj.counterA += 1; obj.off('event', incrA); };
- var incrB = function(){ obj.counterB += 1; obj.off('event', incrB); };
- obj.on('event', incrA);
- obj.on('event', incrB);
- obj.trigger('event');
- obj.trigger('event');
- obj.trigger('event');
- assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');
- assert.equal(obj.counterB, 1, 'counterB should have only been incremented once.');
- });
-
- QUnit.test('bind a callback with a default context when none supplied', function(assert) {
- assert.expect(1);
- var obj = _.extend({
- assertTrue: function() {
- assert.equal(this, obj, '`this` was bound to the callback');
- }
- }, Backbone.Events);
-
- obj.once('event', obj.assertTrue);
- obj.trigger('event');
- });
-
- QUnit.test('bind a callback with a supplied context', function(assert) {
- assert.expect(1);
- var TestClass = function() {
- return this;
- };
- TestClass.prototype.assertTrue = function() {
- assert.ok(true, '`this` was bound to the callback');
- };
-
- var obj = _.extend({}, Backbone.Events);
- obj.on('event', function() { this.assertTrue(); }, new TestClass);
- obj.trigger('event');
- });
-
- QUnit.test('nested trigger with unbind', function(assert) {
- assert.expect(1);
- var obj = {counter: 0};
- _.extend(obj, Backbone.Events);
- var incr1 = function(){ obj.counter += 1; obj.off('event', incr1); obj.trigger('event'); };
- var incr2 = function(){ obj.counter += 1; };
- obj.on('event', incr1);
- obj.on('event', incr2);
- obj.trigger('event');
- assert.equal(obj.counter, 3, 'counter should have been incremented three times');
- });
-
- QUnit.test('callback list is not altered during trigger', function(assert) {
- assert.expect(2);
- var counter = 0, obj = _.extend({}, Backbone.Events);
- var incr = function(){ counter++; };
- var incrOn = function(){ obj.on('event all', incr); };
- var incrOff = function(){ obj.off('event all', incr); };
-
- obj.on('event all', incrOn).trigger('event');
- assert.equal(counter, 0, 'on does not alter callback list');
-
- obj.off().on('event', incrOff).on('event all', incr).trigger('event');
- assert.equal(counter, 2, 'off does not alter callback list');
- });
-
- QUnit.test("#1282 - 'all' callback list is retrieved after each event.", function(assert) {
- assert.expect(1);
- var counter = 0;
- var obj = _.extend({}, Backbone.Events);
- var incr = function(){ counter++; };
- obj.on('x', function() {
- obj.on('y', incr).on('all', incr);
- })
- .trigger('x y');
- assert.strictEqual(counter, 2);
- });
-
- QUnit.test('if no callback is provided, `on` is a noop', function(assert) {
- assert.expect(0);
- _.extend({}, Backbone.Events).on('test').trigger('test');
- });
-
- QUnit.test('if callback is truthy but not a function, `on` should throw an error just like jQuery', function(assert) {
- assert.expect(1);
- var view = _.extend({}, Backbone.Events).on('test', 'noop');
- assert.raises(function() {
- view.trigger('test');
- });
- });
-
- QUnit.test('remove all events for a specific context', function(assert) {
- assert.expect(4);
- var obj = _.extend({}, Backbone.Events);
- obj.on('x y all', function() { assert.ok(true); });
- obj.on('x y all', function() { assert.ok(false); }, obj);
- obj.off(null, null, obj);
- obj.trigger('x y');
- });
-
- QUnit.test('remove all events for a specific callback', function(assert) {
- assert.expect(4);
- var obj = _.extend({}, Backbone.Events);
- var success = function() { assert.ok(true); };
- var fail = function() { assert.ok(false); };
- obj.on('x y all', success);
- obj.on('x y all', fail);
- obj.off(null, fail);
- obj.trigger('x y');
- });
-
- QUnit.test('#1310 - off does not skip consecutive events', function(assert) {
- assert.expect(0);
- var obj = _.extend({}, Backbone.Events);
- obj.on('event', function() { assert.ok(false); }, obj);
- obj.on('event', function() { assert.ok(false); }, obj);
- obj.off(null, null, obj);
- obj.trigger('event');
- });
-
- QUnit.test('once', function(assert) {
- assert.expect(2);
- // Same as the previous test, but we use once rather than having to explicitly unbind
- var obj = {counterA: 0, counterB: 0};
- _.extend(obj, Backbone.Events);
- var incrA = function(){ obj.counterA += 1; obj.trigger('event'); };
- var incrB = function(){ obj.counterB += 1; };
- obj.once('event', incrA);
- obj.once('event', incrB);
- obj.trigger('event');
- assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');
- assert.equal(obj.counterB, 1, 'counterB should have only been incremented once.');
- });
-
- QUnit.test('once variant one', function(assert) {
- assert.expect(3);
- var f = function(){ assert.ok(true); };
-
- var a = _.extend({}, Backbone.Events).once('event', f);
- var b = _.extend({}, Backbone.Events).on('event', f);
-
- a.trigger('event');
-
- b.trigger('event');
- b.trigger('event');
- });
-
- QUnit.test('once variant two', function(assert) {
- assert.expect(3);
- var f = function(){ assert.ok(true); };
- var obj = _.extend({}, Backbone.Events);
-
- obj
- .once('event', f)
- .on('event', f)
- .trigger('event')
- .trigger('event');
- });
-
- QUnit.test('once with off', function(assert) {
- assert.expect(0);
- var f = function(){ assert.ok(true); };
- var obj = _.extend({}, Backbone.Events);
-
- obj.once('event', f);
- obj.off('event', f);
- obj.trigger('event');
- });
-
- QUnit.test('once with event maps', function(assert) {
- var obj = {counter: 0};
- _.extend(obj, Backbone.Events);
-
- var increment = function() {
- this.counter += 1;
- };
-
- obj.once({
- a: increment,
- b: increment,
- c: increment
- }, obj);
-
- obj.trigger('a');
- assert.equal(obj.counter, 1);
-
- obj.trigger('a b');
- assert.equal(obj.counter, 2);
-
- obj.trigger('c');
- assert.equal(obj.counter, 3);
-
- obj.trigger('a b c');
- assert.equal(obj.counter, 3);
- });
-
- QUnit.test('bind a callback with a supplied context using once with object notation', function(assert) {
- assert.expect(1);
- var obj = {counter: 0};
- var context = {};
- _.extend(obj, Backbone.Events);
-
- obj.once({
- a: function() {
- assert.strictEqual(this, context, 'defaults `context` to `callback` param');
- }
- }, context).trigger('a');
- });
-
- QUnit.test('once with off only by context', function(assert) {
- assert.expect(0);
- var context = {};
- var obj = _.extend({}, Backbone.Events);
- obj.once('event', function(){ assert.ok(false); }, context);
- obj.off(null, null, context);
- obj.trigger('event');
- });
-
- QUnit.test('Backbone object inherits Events', function(assert) {
- assert.ok(Backbone.on === Backbone.Events.on);
- });
-
- QUnit.test('once with asynchronous events', function(assert) {
- var done = assert.async();
- assert.expect(1);
- var func = _.debounce(function() { assert.ok(true); done(); }, 50);
- var obj = _.extend({}, Backbone.Events).once('async', func);
-
- obj.trigger('async');
- obj.trigger('async');
- });
-
- QUnit.test('once with multiple events.', function(assert) {
- assert.expect(2);
- var obj = _.extend({}, Backbone.Events);
- obj.once('x y', function() { assert.ok(true); });
- obj.trigger('x y');
- });
-
- QUnit.test('Off during iteration with once.', function(assert) {
- assert.expect(2);
- var obj = _.extend({}, Backbone.Events);
- var f = function(){ this.off('event', f); };
- obj.on('event', f);
- obj.once('event', function(){});
- obj.on('event', function(){ assert.ok(true); });
-
- obj.trigger('event');
- obj.trigger('event');
- });
-
- QUnit.test('`once` on `all` should work as expected', function(assert) {
- assert.expect(1);
- Backbone.once('all', function() {
- assert.ok(true);
- Backbone.trigger('all');
- });
- Backbone.trigger('all');
- });
-
- QUnit.test('once without a callback is a noop', function(assert) {
- assert.expect(0);
- _.extend({}, Backbone.Events).once('event').trigger('event');
- });
-
- QUnit.test('listenToOnce without a callback is a noop', function(assert) {
- assert.expect(0);
- var obj = _.extend({}, Backbone.Events);
- obj.listenToOnce(obj, 'event').trigger('event');
- });
-
- QUnit.test('event functions are chainable', function(assert) {
- var obj = _.extend({}, Backbone.Events);
- var obj2 = _.extend({}, Backbone.Events);
- var fn = function() {};
- assert.equal(obj, obj.trigger('noeventssetyet'));
- assert.equal(obj, obj.off('noeventssetyet'));
- assert.equal(obj, obj.stopListening('noeventssetyet'));
- assert.equal(obj, obj.on('a', fn));
- assert.equal(obj, obj.once('c', fn));
- assert.equal(obj, obj.trigger('a'));
- assert.equal(obj, obj.listenTo(obj2, 'a', fn));
- assert.equal(obj, obj.listenToOnce(obj2, 'b', fn));
- assert.equal(obj, obj.off('a c'));
- assert.equal(obj, obj.stopListening(obj2, 'a'));
- assert.equal(obj, obj.stopListening());
- });
-
- QUnit.test('#3448 - listenToOnce with space-separated events', function(assert) {
- assert.expect(2);
- var one = _.extend({}, Backbone.Events);
- var two = _.extend({}, Backbone.Events);
- var count = 1;
- one.listenToOnce(two, 'x y', function(n) { assert.ok(n === count++); });
- two.trigger('x', 1);
- two.trigger('x', 1);
- two.trigger('y', 2);
- two.trigger('y', 2);
- });
-
-})();
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/model.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/model.js
deleted file mode 100644
index b73a1c79..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/model.js
+++ /dev/null
@@ -1,1418 +0,0 @@
-(function() {
-
- var ProxyModel = Backbone.Model.extend();
- var Klass = Backbone.Collection.extend({
- url: function() { return '/collection'; }
- });
- var doc, collection;
-
- QUnit.module('Backbone.Model', {
-
- beforeEach: function(assert) {
- doc = new ProxyModel({
- id: '1-the-tempest',
- title: 'The Tempest',
- author: 'Bill Shakespeare',
- length: 123
- });
- collection = new Klass();
- collection.add(doc);
- }
-
- });
-
- QUnit.test('initialize', function(assert) {
- assert.expect(3);
- var Model = Backbone.Model.extend({
- initialize: function() {
- this.one = 1;
- assert.equal(this.collection, collection);
- }
- });
- var model = new Model({}, {collection: collection});
- assert.equal(model.one, 1);
- assert.equal(model.collection, collection);
- });
-
- QUnit.test('Object.prototype properties are overridden by attributes', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model({hasOwnProperty: true});
- assert.equal(model.get('hasOwnProperty'), true);
- });
-
- QUnit.test('initialize with attributes and options', function(assert) {
- assert.expect(1);
- var Model = Backbone.Model.extend({
- initialize: function(attributes, options) {
- this.one = options.one;
- }
- });
- var model = new Model({}, {one: 1});
- assert.equal(model.one, 1);
- });
-
- QUnit.test('initialize with parsed attributes', function(assert) {
- assert.expect(1);
- var Model = Backbone.Model.extend({
- parse: function(attrs) {
- attrs.value += 1;
- return attrs;
- }
- });
- var model = new Model({value: 1}, {parse: true});
- assert.equal(model.get('value'), 2);
- });
-
- QUnit.test('parse can return null', function(assert) {
- assert.expect(1);
- var Model = Backbone.Model.extend({
- parse: function(attrs) {
- attrs.value += 1;
- return null;
- }
- });
- var model = new Model({value: 1}, {parse: true});
- assert.equal(JSON.stringify(model.toJSON()), '{}');
- });
-
- QUnit.test('url', function(assert) {
- assert.expect(3);
- doc.urlRoot = null;
- assert.equal(doc.url(), '/collection/1-the-tempest');
- doc.collection.url = '/collection/';
- assert.equal(doc.url(), '/collection/1-the-tempest');
- doc.collection = null;
- assert.raises(function() { doc.url(); });
- doc.collection = collection;
- });
-
- QUnit.test('url when using urlRoot, and uri encoding', function(assert) {
- assert.expect(2);
- var Model = Backbone.Model.extend({
- urlRoot: '/collection'
- });
- var model = new Model();
- assert.equal(model.url(), '/collection');
- model.set({id: '+1+'});
- assert.equal(model.url(), '/collection/%2B1%2B');
- });
-
- QUnit.test('url when using urlRoot as a function to determine urlRoot at runtime', function(assert) {
- assert.expect(2);
- var Model = Backbone.Model.extend({
- urlRoot: function() {
- return '/nested/' + this.get('parentId') + '/collection';
- }
- });
-
- var model = new Model({parentId: 1});
- assert.equal(model.url(), '/nested/1/collection');
- model.set({id: 2});
- assert.equal(model.url(), '/nested/1/collection/2');
- });
-
- QUnit.test('underscore methods', function(assert) {
- assert.expect(5);
- var model = new Backbone.Model({foo: 'a', bar: 'b', baz: 'c'});
- var model2 = model.clone();
- assert.deepEqual(model.keys(), ['foo', 'bar', 'baz']);
- assert.deepEqual(model.values(), ['a', 'b', 'c']);
- assert.deepEqual(model.invert(), {a: 'foo', b: 'bar', c: 'baz'});
- assert.deepEqual(model.pick('foo', 'baz'), {foo: 'a', baz: 'c'});
- assert.deepEqual(model.omit('foo', 'bar'), {baz: 'c'});
- });
-
- QUnit.test('chain', function(assert) {
- var model = new Backbone.Model({a: 0, b: 1, c: 2});
- assert.deepEqual(model.chain().pick('a', 'b', 'c').values().compact().value(), [1, 2]);
- });
-
- QUnit.test('clone', function(assert) {
- assert.expect(10);
- var a = new Backbone.Model({foo: 1, bar: 2, baz: 3});
- var b = a.clone();
- assert.equal(a.get('foo'), 1);
- assert.equal(a.get('bar'), 2);
- assert.equal(a.get('baz'), 3);
- assert.equal(b.get('foo'), a.get('foo'), 'Foo should be the same on the clone.');
- assert.equal(b.get('bar'), a.get('bar'), 'Bar should be the same on the clone.');
- assert.equal(b.get('baz'), a.get('baz'), 'Baz should be the same on the clone.');
- a.set({foo: 100});
- assert.equal(a.get('foo'), 100);
- assert.equal(b.get('foo'), 1, 'Changing a parent attribute does not change the clone.');
-
- var foo = new Backbone.Model({p: 1});
- var bar = new Backbone.Model({p: 2});
- bar.set(foo.clone().attributes, {unset: true});
- assert.equal(foo.get('p'), 1);
- assert.equal(bar.get('p'), undefined);
- });
-
- QUnit.test('isNew', function(assert) {
- assert.expect(6);
- var a = new Backbone.Model({foo: 1, bar: 2, baz: 3});
- assert.ok(a.isNew(), 'it should be new');
- a = new Backbone.Model({foo: 1, bar: 2, baz: 3, id: -5});
- assert.ok(!a.isNew(), 'any defined ID is legal, negative or positive');
- a = new Backbone.Model({foo: 1, bar: 2, baz: 3, id: 0});
- assert.ok(!a.isNew(), 'any defined ID is legal, including zero');
- assert.ok(new Backbone.Model().isNew(), 'is true when there is no id');
- assert.ok(!new Backbone.Model({id: 2}).isNew(), 'is false for a positive integer');
- assert.ok(!new Backbone.Model({id: -5}).isNew(), 'is false for a negative integer');
- });
-
- QUnit.test('get', function(assert) {
- assert.expect(2);
- assert.equal(doc.get('title'), 'The Tempest');
- assert.equal(doc.get('author'), 'Bill Shakespeare');
- });
-
- QUnit.test('escape', function(assert) {
- assert.expect(5);
- assert.equal(doc.escape('title'), 'The Tempest');
- doc.set({audience: 'Bill & Bob'});
- assert.equal(doc.escape('audience'), 'Bill &amp; Bob');
- doc.set({audience: 'Tim > Joan'});
- assert.equal(doc.escape('audience'), 'Tim &gt; Joan');
- doc.set({audience: 10101});
- assert.equal(doc.escape('audience'), '10101');
- doc.unset('audience');
- assert.equal(doc.escape('audience'), '');
- });
-
- QUnit.test('has', function(assert) {
- assert.expect(10);
- var model = new Backbone.Model();
-
- assert.strictEqual(model.has('name'), false);
-
- model.set({
- '0': 0,
- '1': 1,
- 'true': true,
- 'false': false,
- 'empty': '',
- 'name': 'name',
- 'null': null,
- 'undefined': undefined
- });
-
- assert.strictEqual(model.has('0'), true);
- assert.strictEqual(model.has('1'), true);
- assert.strictEqual(model.has('true'), true);
- assert.strictEqual(model.has('false'), true);
- assert.strictEqual(model.has('empty'), true);
- assert.strictEqual(model.has('name'), true);
-
- model.unset('name');
-
- assert.strictEqual(model.has('name'), false);
- assert.strictEqual(model.has('null'), false);
- assert.strictEqual(model.has('undefined'), false);
- });
-
- QUnit.test('matches', function(assert) {
- assert.expect(4);
- var model = new Backbone.Model();
-
- assert.strictEqual(model.matches({name: 'Jonas', cool: true}), false);
-
- model.set({name: 'Jonas', cool: true});
-
- assert.strictEqual(model.matches({name: 'Jonas'}), true);
- assert.strictEqual(model.matches({name: 'Jonas', cool: true}), true);
- assert.strictEqual(model.matches({name: 'Jonas', cool: false}), false);
- });
-
- QUnit.test('matches with predicate', function(assert) {
- var model = new Backbone.Model({a: 0});
-
- assert.strictEqual(model.matches(function(attr) {
- return attr.a > 1 && attr.b != null;
- }), false);
-
- model.set({a: 3, b: true});
-
- assert.strictEqual(model.matches(function(attr) {
- return attr.a > 1 && attr.b != null;
- }), true);
- });
-
- QUnit.test('set and unset', function(assert) {
- assert.expect(8);
- var a = new Backbone.Model({id: 'id', foo: 1, bar: 2, baz: 3});
- var changeCount = 0;
- a.on('change:foo', function() { changeCount += 1; });
- a.set({foo: 2});
- assert.equal(a.get('foo'), 2, 'Foo should have changed.');
- assert.equal(changeCount, 1, 'Change count should have incremented.');
- // set with value that is not new shouldn't fire change event
- a.set({foo: 2});
- assert.equal(a.get('foo'), 2, 'Foo should NOT have changed, still 2');
- assert.equal(changeCount, 1, 'Change count should NOT have incremented.');
-
- a.validate = function(attrs) {
- assert.equal(attrs.foo, void 0, 'validate:true passed while unsetting');
- };
- a.unset('foo', {validate: true});
- assert.equal(a.get('foo'), void 0, 'Foo should have changed');
- delete a.validate;
- assert.equal(changeCount, 2, 'Change count should have incremented for unset.');
-
- a.unset('id');
- assert.equal(a.id, undefined, 'Unsetting the id should remove the id property.');
- });
-
- QUnit.test('#2030 - set with failed validate, followed by another set triggers change', function(assert) {
- var attr = 0, main = 0, error = 0;
- var Model = Backbone.Model.extend({
- validate: function(attrs) {
- if (attrs.x > 1) {
- error++;
- return 'this is an error';
- }
- }
- });
- var model = new Model({x: 0});
- model.on('change:x', function() { attr++; });
- model.on('change', function() { main++; });
- model.set({x: 2}, {validate: true});
- model.set({x: 1}, {validate: true});
- assert.deepEqual([attr, main, error], [1, 1, 1]);
- });
-
- QUnit.test('set triggers changes in the correct order', function(assert) {
- var value = null;
- var model = new Backbone.Model;
- model.on('last', function(){ value = 'last'; });
- model.on('first', function(){ value = 'first'; });
- model.trigger('first');
- model.trigger('last');
- assert.equal(value, 'last');
- });
-
- QUnit.test('set falsy values in the correct order', function(assert) {
- assert.expect(2);
- var model = new Backbone.Model({result: 'result'});
- model.on('change', function() {
- assert.equal(model.changed.result, void 0);
- assert.equal(model.previous('result'), false);
- });
- model.set({result: void 0}, {silent: true});
- model.set({result: null}, {silent: true});
- model.set({result: false}, {silent: true});
- model.set({result: void 0});
- });
-
- QUnit.test('nested set triggers with the correct options', function(assert) {
- var model = new Backbone.Model();
- var o1 = {};
- var o2 = {};
- var o3 = {};
- model.on('change', function(__, options) {
- switch (model.get('a')) {
- case 1:
- assert.equal(options, o1);
- return model.set('a', 2, o2);
- case 2:
- assert.equal(options, o2);
- return model.set('a', 3, o3);
- case 3:
- assert.equal(options, o3);
- }
- });
- model.set('a', 1, o1);
- });
-
- QUnit.test('multiple unsets', function(assert) {
- assert.expect(1);
- var i = 0;
- var counter = function(){ i++; };
- var model = new Backbone.Model({a: 1});
- model.on('change:a', counter);
- model.set({a: 2});
- model.unset('a');
- model.unset('a');
- assert.equal(i, 2, 'Unset does not fire an event for missing attributes.');
- });
-
- QUnit.test('unset and changedAttributes', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model({a: 1});
- model.on('change', function() {
- assert.ok('a' in model.changedAttributes(), 'changedAttributes should contain unset properties');
- });
- model.unset('a');
- });
-
- QUnit.test('using a non-default id attribute.', function(assert) {
- assert.expect(5);
- var MongoModel = Backbone.Model.extend({idAttribute: '_id'});
- var model = new MongoModel({id: 'eye-dee', _id: 25, title: 'Model'});
- assert.equal(model.get('id'), 'eye-dee');
- assert.equal(model.id, 25);
- assert.equal(model.isNew(), false);
- model.unset('_id');
- assert.equal(model.id, undefined);
- assert.equal(model.isNew(), true);
- });
-
- QUnit.test('setting an alternative cid prefix', function(assert) {
- assert.expect(4);
- var Model = Backbone.Model.extend({
- cidPrefix: 'm'
- });
- var model = new Model();
-
- assert.equal(model.cid.charAt(0), 'm');
-
- model = new Backbone.Model();
- assert.equal(model.cid.charAt(0), 'c');
-
- var Collection = Backbone.Collection.extend({
- model: Model
- });
- var col = new Collection([{id: 'c5'}, {id: 'c6'}, {id: 'c7'}]);
-
- assert.equal(col.get('c6').cid.charAt(0), 'm');
- col.set([{id: 'c6', value: 'test'}], {
- merge: true,
- add: true,
- remove: false
- });
- assert.ok(col.get('c6').has('value'));
- });
-
- QUnit.test('set an empty string', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model({name: 'Model'});
- model.set({name: ''});
- assert.equal(model.get('name'), '');
- });
-
- QUnit.test('setting an object', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model({
- custom: {foo: 1}
- });
- model.on('change', function() {
- assert.ok(1);
- });
- model.set({
- custom: {foo: 1} // no change should be fired
- });
- model.set({
- custom: {foo: 2} // change event should be fired
- });
- });
-
- QUnit.test('clear', function(assert) {
- assert.expect(3);
- var changed;
- var model = new Backbone.Model({id: 1, name: 'Model'});
- model.on('change:name', function(){ changed = true; });
- model.on('change', function() {
- var changedAttrs = model.changedAttributes();
- assert.ok('name' in changedAttrs);
- });
- model.clear();
- assert.equal(changed, true);
- assert.equal(model.get('name'), undefined);
- });
-
- QUnit.test('defaults', function(assert) {
- assert.expect(9);
- var Defaulted = Backbone.Model.extend({
- defaults: {
- one: 1,
- two: 2
- }
- });
- var model = new Defaulted({two: undefined});
- assert.equal(model.get('one'), 1);
- assert.equal(model.get('two'), 2);
- model = new Defaulted({two: 3});
- assert.equal(model.get('one'), 1);
- assert.equal(model.get('two'), 3);
- Defaulted = Backbone.Model.extend({
- defaults: function() {
- return {
- one: 3,
- two: 4
- };
- }
- });
- model = new Defaulted({two: undefined});
- assert.equal(model.get('one'), 3);
- assert.equal(model.get('two'), 4);
- Defaulted = Backbone.Model.extend({
- defaults: {hasOwnProperty: true}
- });
- model = new Defaulted();
- assert.equal(model.get('hasOwnProperty'), true);
- model = new Defaulted({hasOwnProperty: undefined});
- assert.equal(model.get('hasOwnProperty'), true);
- model = new Defaulted({hasOwnProperty: false});
- assert.equal(model.get('hasOwnProperty'), false);
- });
-
- QUnit.test('change, hasChanged, changedAttributes, previous, previousAttributes', function(assert) {
- assert.expect(9);
- var model = new Backbone.Model({name: 'Tim', age: 10});
- assert.deepEqual(model.changedAttributes(), false);
- model.on('change', function() {
- assert.ok(model.hasChanged('name'), 'name changed');
- assert.ok(!model.hasChanged('age'), 'age did not');
- assert.ok(_.isEqual(model.changedAttributes(), {name: 'Rob'}), 'changedAttributes returns the changed attrs');
- assert.equal(model.previous('name'), 'Tim');
- assert.ok(_.isEqual(model.previousAttributes(), {name: 'Tim', age: 10}), 'previousAttributes is correct');
- });
- assert.equal(model.hasChanged(), false);
- assert.equal(model.hasChanged(undefined), false);
- model.set({name: 'Rob'});
- assert.equal(model.get('name'), 'Rob');
- });
-
- QUnit.test('changedAttributes', function(assert) {
- assert.expect(3);
- var model = new Backbone.Model({a: 'a', b: 'b'});
- assert.deepEqual(model.changedAttributes(), false);
- assert.equal(model.changedAttributes({a: 'a'}), false);
- assert.equal(model.changedAttributes({a: 'b'}).a, 'b');
- });
-
- QUnit.test('change with options', function(assert) {
- assert.expect(2);
- var value;
- var model = new Backbone.Model({name: 'Rob'});
- model.on('change', function(m, options) {
- value = options.prefix + m.get('name');
- });
- model.set({name: 'Bob'}, {prefix: 'Mr. '});
- assert.equal(value, 'Mr. Bob');
- model.set({name: 'Sue'}, {prefix: 'Ms. '});
- assert.equal(value, 'Ms. Sue');
- });
-
- QUnit.test('change after initialize', function(assert) {
- assert.expect(1);
- var changed = 0;
- var attrs = {id: 1, label: 'c'};
- var obj = new Backbone.Model(attrs);
- obj.on('change', function() { changed += 1; });
- obj.set(attrs);
- assert.equal(changed, 0);
- });
-
- QUnit.test('save within change event', function(assert) {
- assert.expect(1);
- var env = this;
- var model = new Backbone.Model({firstName: 'Taylor', lastName: 'Swift'});
- model.url = '/test';
- model.on('change', function() {
- model.save();
- assert.ok(_.isEqual(env.syncArgs.model, model));
- });
- model.set({lastName: 'Hicks'});
- });
-
- QUnit.test('validate after save', function(assert) {
- assert.expect(2);
- var lastError, model = new Backbone.Model();
- model.validate = function(attrs) {
- if (attrs.admin) return "Can't change admin status.";
- };
- model.sync = function(method, m, options) {
- options.success.call(this, {admin: true});
- };
- model.on('invalid', function(m, error) {
- lastError = error;
- });
- model.save(null);
-
- assert.equal(lastError, "Can't change admin status.");
- assert.equal(model.validationError, "Can't change admin status.");
- });
-
- QUnit.test('save', function(assert) {
- assert.expect(2);
- doc.save({title: 'Henry V'});
- assert.equal(this.syncArgs.method, 'update');
- assert.ok(_.isEqual(this.syncArgs.model, doc));
- });
-
- QUnit.test('save, fetch, destroy triggers error event when an error occurs', function(assert) {
- assert.expect(3);
- var model = new Backbone.Model();
- model.on('error', function() {
- assert.ok(true);
- });
- model.sync = function(method, m, options) {
- options.error();
- };
- model.save({data: 2, id: 1});
- model.fetch();
- model.destroy();
- });
-
- QUnit.test('#3283 - save, fetch, destroy calls success with context', function(assert) {
- assert.expect(3);
- var model = new Backbone.Model();
- var obj = {};
- var options = {
- context: obj,
- success: function() {
- assert.equal(this, obj);
- }
- };
- model.sync = function(method, m, opts) {
- opts.success.call(opts.context);
- };
- model.save({data: 2, id: 1}, options);
- model.fetch(options);
- model.destroy(options);
- });
-
- QUnit.test('#3283 - save, fetch, destroy calls error with context', function(assert) {
- assert.expect(3);
- var model = new Backbone.Model();
- var obj = {};
- var options = {
- context: obj,
- error: function() {
- assert.equal(this, obj);
- }
- };
- model.sync = function(method, m, opts) {
- opts.error.call(opts.context);
- };
- model.save({data: 2, id: 1}, options);
- model.fetch(options);
- model.destroy(options);
- });
-
- QUnit.test('#3470 - save and fetch with parse false', function(assert) {
- assert.expect(2);
- var i = 0;
- var model = new Backbone.Model();
- model.parse = function() {
- assert.ok(false);
- };
- model.sync = function(method, m, options) {
- options.success({i: ++i});
- };
- model.fetch({parse: false});
- assert.equal(model.get('i'), i);
- model.save(null, {parse: false});
- assert.equal(model.get('i'), i);
- });
-
- QUnit.test('save with PATCH', function(assert) {
- doc.clear().set({id: 1, a: 1, b: 2, c: 3, d: 4});
- doc.save();
- assert.equal(this.syncArgs.method, 'update');
- assert.equal(this.syncArgs.options.attrs, undefined);
-
- doc.save({b: 2, d: 4}, {patch: true});
- assert.equal(this.syncArgs.method, 'patch');
- assert.equal(_.size(this.syncArgs.options.attrs), 2);
- assert.equal(this.syncArgs.options.attrs.d, 4);
- assert.equal(this.syncArgs.options.attrs.a, undefined);
- assert.equal(this.ajaxSettings.data, '{"b":2,"d":4}');
- });
-
- QUnit.test('save with PATCH and different attrs', function(assert) {
- doc.clear().save({b: 2, d: 4}, {patch: true, attrs: {B: 1, D: 3}});
- assert.equal(this.syncArgs.options.attrs.D, 3);
- assert.equal(this.syncArgs.options.attrs.d, undefined);
- assert.equal(this.ajaxSettings.data, '{"B":1,"D":3}');
- assert.deepEqual(doc.attributes, {b: 2, d: 4});
- });
-
- QUnit.test('save in positional style', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model();
- model.sync = function(method, m, options) {
- options.success();
- };
- model.save('title', 'Twelfth Night');
- assert.equal(model.get('title'), 'Twelfth Night');
- });
-
- QUnit.test('save with non-object success response', function(assert) {
- assert.expect(2);
- var model = new Backbone.Model();
- model.sync = function(method, m, options) {
- options.success('', options);
- options.success(null, options);
- };
- model.save({testing: 'empty'}, {
- success: function(m) {
- assert.deepEqual(m.attributes, {testing: 'empty'});
- }
- });
- });
-
- QUnit.test('save with wait and supplied id', function(assert) {
- var Model = Backbone.Model.extend({
- urlRoot: '/collection'
- });
- var model = new Model();
- model.save({id: 42}, {wait: true});
- assert.equal(this.ajaxSettings.url, '/collection/42');
- });
-
- QUnit.test('save will pass extra options to success callback', function(assert) {
- assert.expect(1);
- var SpecialSyncModel = Backbone.Model.extend({
- sync: function(method, m, options) {
- _.extend(options, {specialSync: true});
- return Backbone.Model.prototype.sync.call(this, method, m, options);
- },
- urlRoot: '/test'
- });
-
- var model = new SpecialSyncModel();
-
- var onSuccess = function(m, response, options) {
- assert.ok(options.specialSync, 'Options were passed correctly to callback');
- };
-
- model.save(null, {success: onSuccess});
- this.ajaxSettings.success();
- });
-
- QUnit.test('fetch', function(assert) {
- assert.expect(2);
- doc.fetch();
- assert.equal(this.syncArgs.method, 'read');
- assert.ok(_.isEqual(this.syncArgs.model, doc));
- });
-
- QUnit.test('fetch will pass extra options to success callback', function(assert) {
- assert.expect(1);
- var SpecialSyncModel = Backbone.Model.extend({
- sync: function(method, m, options) {
- _.extend(options, {specialSync: true});
- return Backbone.Model.prototype.sync.call(this, method, m, options);
- },
- urlRoot: '/test'
- });
-
- var model = new SpecialSyncModel();
-
- var onSuccess = function(m, response, options) {
- assert.ok(options.specialSync, 'Options were passed correctly to callback');
- };
-
- model.fetch({success: onSuccess});
- this.ajaxSettings.success();
- });
-
- QUnit.test('destroy', function(assert) {
- assert.expect(3);
- doc.destroy();
- assert.equal(this.syncArgs.method, 'delete');
- assert.ok(_.isEqual(this.syncArgs.model, doc));
-
- var newModel = new Backbone.Model;
- assert.equal(newModel.destroy(), false);
- });
-
- QUnit.test('destroy will pass extra options to success callback', function(assert) {
- assert.expect(1);
- var SpecialSyncModel = Backbone.Model.extend({
- sync: function(method, m, options) {
- _.extend(options, {specialSync: true});
- return Backbone.Model.prototype.sync.call(this, method, m, options);
- },
- urlRoot: '/test'
- });
-
- var model = new SpecialSyncModel({id: 'id'});
-
- var onSuccess = function(m, response, options) {
- assert.ok(options.specialSync, 'Options were passed correctly to callback');
- };
-
- model.destroy({success: onSuccess});
- this.ajaxSettings.success();
- });
-
- QUnit.test('non-persisted destroy', function(assert) {
- assert.expect(1);
- var a = new Backbone.Model({foo: 1, bar: 2, baz: 3});
- a.sync = function() { throw 'should not be called'; };
- a.destroy();
- assert.ok(true, 'non-persisted model should not call sync');
- });
-
- QUnit.test('validate', function(assert) {
- var lastError;
- var model = new Backbone.Model();
- model.validate = function(attrs) {
- if (attrs.admin !== this.get('admin')) return "Can't change admin status.";
- };
- model.on('invalid', function(m, error) {
- lastError = error;
- });
- var result = model.set({a: 100});
- assert.equal(result, model);
- assert.equal(model.get('a'), 100);
- assert.equal(lastError, undefined);
- result = model.set({admin: true});
- assert.equal(model.get('admin'), true);
- result = model.set({a: 200, admin: false}, {validate: true});
- assert.equal(lastError, "Can't change admin status.");
- assert.equal(result, false);
- assert.equal(model.get('a'), 100);
- });
-
- QUnit.test('validate on unset and clear', function(assert) {
- assert.expect(6);
- var error;
- var model = new Backbone.Model({name: 'One'});
- model.validate = function(attrs) {
- if (!attrs.name) {
- error = true;
- return 'No thanks.';
- }
- };
- model.set({name: 'Two'});
- assert.equal(model.get('name'), 'Two');
- assert.equal(error, undefined);
- model.unset('name', {validate: true});
- assert.equal(error, true);
- assert.equal(model.get('name'), 'Two');
- model.clear({validate: true});
- assert.equal(model.get('name'), 'Two');
- delete model.validate;
- model.clear();
- assert.equal(model.get('name'), undefined);
- });
-
- QUnit.test('validate with error callback', function(assert) {
- assert.expect(8);
- var lastError, boundError;
- var model = new Backbone.Model();
- model.validate = function(attrs) {
- if (attrs.admin) return "Can't change admin status.";
- };
- model.on('invalid', function(m, error) {
- boundError = true;
- });
- var result = model.set({a: 100}, {validate: true});
- assert.equal(result, model);
- assert.equal(model.get('a'), 100);
- assert.equal(model.validationError, null);
- assert.equal(boundError, undefined);
- result = model.set({a: 200, admin: true}, {validate: true});
- assert.equal(result, false);
- assert.equal(model.get('a'), 100);
- assert.equal(model.validationError, "Can't change admin status.");
- assert.equal(boundError, true);
- });
-
- QUnit.test('defaults always extend attrs (#459)', function(assert) {
- assert.expect(2);
- var Defaulted = Backbone.Model.extend({
- defaults: {one: 1},
- initialize: function(attrs, opts) {
- assert.equal(this.attributes.one, 1);
- }
- });
- var providedattrs = new Defaulted({});
- var emptyattrs = new Defaulted();
- });
-
- QUnit.test('Inherit class properties', function(assert) {
- assert.expect(6);
- var Parent = Backbone.Model.extend({
- instancePropSame: function() {},
- instancePropDiff: function() {}
- }, {
- classProp: function() {}
- });
- var Child = Parent.extend({
- instancePropDiff: function() {}
- });
-
- var adult = new Parent;
- var kid = new Child;
-
- assert.equal(Child.classProp, Parent.classProp);
- assert.notEqual(Child.classProp, undefined);
-
- assert.equal(kid.instancePropSame, adult.instancePropSame);
- assert.notEqual(kid.instancePropSame, undefined);
-
- assert.notEqual(Child.prototype.instancePropDiff, Parent.prototype.instancePropDiff);
- assert.notEqual(Child.prototype.instancePropDiff, undefined);
- });
-
- QUnit.test("Nested change events don't clobber previous attributes", function(assert) {
- assert.expect(4);
- new Backbone.Model()
- .on('change:state', function(m, newState) {
- assert.equal(m.previous('state'), undefined);
- assert.equal(newState, 'hello');
- // Fire a nested change event.
- m.set({other: 'whatever'});
- })
- .on('change:state', function(m, newState) {
- assert.equal(m.previous('state'), undefined);
- assert.equal(newState, 'hello');
- })
- .set({state: 'hello'});
- });
-
- QUnit.test('hasChanged/set should use same comparison', function(assert) {
- assert.expect(2);
- var changed = 0, model = new Backbone.Model({a: null});
- model.on('change', function() {
- assert.ok(this.hasChanged('a'));
- })
- .on('change:a', function() {
- changed++;
- })
- .set({a: undefined});
- assert.equal(changed, 1);
- });
-
- QUnit.test('#582, #425, change:attribute callbacks should fire after all changes have occurred', function(assert) {
- assert.expect(9);
- var model = new Backbone.Model;
-
- var assertion = function() {
- assert.equal(model.get('a'), 'a');
- assert.equal(model.get('b'), 'b');
- assert.equal(model.get('c'), 'c');
- };
-
- model.on('change:a', assertion);
- model.on('change:b', assertion);
- model.on('change:c', assertion);
-
- model.set({a: 'a', b: 'b', c: 'c'});
- });
-
- QUnit.test('#871, set with attributes property', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model();
- model.set({attributes: true});
- assert.ok(model.has('attributes'));
- });
-
- QUnit.test('set value regardless of equality/change', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model({x: []});
- var a = [];
- model.set({x: a});
- assert.ok(model.get('x') === a);
- });
-
- QUnit.test('set same value does not trigger change', function(assert) {
- assert.expect(0);
- var model = new Backbone.Model({x: 1});
- model.on('change change:x', function() { assert.ok(false); });
- model.set({x: 1});
- model.set({x: 1});
- });
-
- QUnit.test('unset does not fire a change for undefined attributes', function(assert) {
- assert.expect(0);
- var model = new Backbone.Model({x: undefined});
- model.on('change:x', function(){ assert.ok(false); });
- model.unset('x');
- });
-
- QUnit.test('set: undefined values', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model({x: undefined});
- assert.ok('x' in model.attributes);
- });
-
- QUnit.test('hasChanged works outside of change events, and true within', function(assert) {
- assert.expect(6);
- var model = new Backbone.Model({x: 1});
- model.on('change:x', function() {
- assert.ok(model.hasChanged('x'));
- assert.equal(model.get('x'), 1);
- });
- model.set({x: 2}, {silent: true});
- assert.ok(model.hasChanged());
- assert.equal(model.hasChanged('x'), true);
- model.set({x: 1});
- assert.ok(model.hasChanged());
- assert.equal(model.hasChanged('x'), true);
- });
-
- QUnit.test('hasChanged gets cleared on the following set', function(assert) {
- assert.expect(4);
- var model = new Backbone.Model;
- model.set({x: 1});
- assert.ok(model.hasChanged());
- model.set({x: 1});
- assert.ok(!model.hasChanged());
- model.set({x: 2});
- assert.ok(model.hasChanged());
- model.set({});
- assert.ok(!model.hasChanged());
- });
-
- QUnit.test('save with `wait` succeeds without `validate`', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model();
- model.url = '/test';
- model.save({x: 1}, {wait: true});
- assert.ok(this.syncArgs.model === model);
- });
-
- QUnit.test("save without `wait` doesn't set invalid attributes", function(assert) {
- var model = new Backbone.Model();
- model.validate = function() { return 1; };
- model.save({a: 1});
- assert.equal(model.get('a'), void 0);
- });
-
- QUnit.test("save doesn't validate twice", function(assert) {
- var model = new Backbone.Model();
- var times = 0;
- model.sync = function() {};
- model.validate = function() { ++times; };
- model.save({});
- assert.equal(times, 1);
- });
-
- QUnit.test('`hasChanged` for falsey keys', function(assert) {
- assert.expect(2);
- var model = new Backbone.Model();
- model.set({x: true}, {silent: true});
- assert.ok(!model.hasChanged(0));
- assert.ok(!model.hasChanged(''));
- });
-
- QUnit.test('`previous` for falsey keys', function(assert) {
- assert.expect(2);
- var model = new Backbone.Model({'0': true, '': true});
- model.set({'0': false, '': false}, {silent: true});
- assert.equal(model.previous(0), true);
- assert.equal(model.previous(''), true);
- });
-
- QUnit.test('`save` with `wait` sends correct attributes', function(assert) {
- assert.expect(5);
- var changed = 0;
- var model = new Backbone.Model({x: 1, y: 2});
- model.url = '/test';
- model.on('change:x', function() { changed++; });
- model.save({x: 3}, {wait: true});
- assert.deepEqual(JSON.parse(this.ajaxSettings.data), {x: 3, y: 2});
- assert.equal(model.get('x'), 1);
- assert.equal(changed, 0);
- this.syncArgs.options.success({});
- assert.equal(model.get('x'), 3);
- assert.equal(changed, 1);
- });
-
- QUnit.test("a failed `save` with `wait` doesn't leave attributes behind", function(assert) {
- assert.expect(1);
- var model = new Backbone.Model;
- model.url = '/test';
- model.save({x: 1}, {wait: true});
- assert.equal(model.get('x'), void 0);
- });
-
- QUnit.test('#1030 - `save` with `wait` results in correct attributes if success is called during sync', function(assert) {
- assert.expect(2);
- var model = new Backbone.Model({x: 1, y: 2});
- model.sync = function(method, m, options) {
- options.success();
- };
- model.on('change:x', function() { assert.ok(true); });
- model.save({x: 3}, {wait: true});
- assert.equal(model.get('x'), 3);
- });
-
- QUnit.test('save with wait validates attributes', function(assert) {
- var model = new Backbone.Model();
- model.url = '/test';
- model.validate = function() { assert.ok(true); };
- model.save({x: 1}, {wait: true});
- });
-
- QUnit.test('save turns on parse flag', function(assert) {
- var Model = Backbone.Model.extend({
- sync: function(method, m, options) { assert.ok(options.parse); }
- });
- new Model().save();
- });
-
- QUnit.test("nested `set` during `'change:attr'`", function(assert) {
- assert.expect(2);
- var events = [];
- var model = new Backbone.Model();
- model.on('all', function(event) { events.push(event); });
- model.on('change', function() {
- model.set({z: true}, {silent: true});
- });
- model.on('change:x', function() {
- model.set({y: true});
- });
- model.set({x: true});
- assert.deepEqual(events, ['change:y', 'change:x', 'change']);
- events = [];
- model.set({z: true});
- assert.deepEqual(events, []);
- });
-
- QUnit.test('nested `change` only fires once', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model();
- model.on('change', function() {
- assert.ok(true);
- model.set({x: true});
- });
- model.set({x: true});
- });
-
- QUnit.test("nested `set` during `'change'`", function(assert) {
- assert.expect(6);
- var count = 0;
- var model = new Backbone.Model();
- model.on('change', function() {
- switch (count++) {
- case 0:
- assert.deepEqual(this.changedAttributes(), {x: true});
- assert.equal(model.previous('x'), undefined);
- model.set({y: true});
- break;
- case 1:
- assert.deepEqual(this.changedAttributes(), {x: true, y: true});
- assert.equal(model.previous('x'), undefined);
- model.set({z: true});
- break;
- case 2:
- assert.deepEqual(this.changedAttributes(), {x: true, y: true, z: true});
- assert.equal(model.previous('y'), undefined);
- break;
- default:
- assert.ok(false);
- }
- });
- model.set({x: true});
- });
-
- QUnit.test('nested `change` with silent', function(assert) {
- assert.expect(3);
- var count = 0;
- var model = new Backbone.Model();
- model.on('change:y', function() { assert.ok(false); });
- model.on('change', function() {
- switch (count++) {
- case 0:
- assert.deepEqual(this.changedAttributes(), {x: true});
- model.set({y: true}, {silent: true});
- model.set({z: true});
- break;
- case 1:
- assert.deepEqual(this.changedAttributes(), {x: true, y: true, z: true});
- break;
- case 2:
- assert.deepEqual(this.changedAttributes(), {z: false});
- break;
- default:
- assert.ok(false);
- }
- });
- model.set({x: true});
- model.set({z: false});
- });
-
- QUnit.test('nested `change:attr` with silent', function(assert) {
- assert.expect(0);
- var model = new Backbone.Model();
- model.on('change:y', function(){ assert.ok(false); });
- model.on('change', function() {
- model.set({y: true}, {silent: true});
- model.set({z: true});
- });
- model.set({x: true});
- });
-
- QUnit.test('multiple nested changes with silent', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model();
- model.on('change:x', function() {
- model.set({y: 1}, {silent: true});
- model.set({y: 2});
- });
- model.on('change:y', function(m, val) {
- assert.equal(val, 2);
- });
- model.set({x: true});
- });
-
- QUnit.test('multiple nested changes with silent', function(assert) {
- assert.expect(1);
- var changes = [];
- var model = new Backbone.Model();
- model.on('change:b', function(m, val) { changes.push(val); });
- model.on('change', function() {
- model.set({b: 1});
- });
- model.set({b: 0});
- assert.deepEqual(changes, [0, 1]);
- });
-
- QUnit.test('basic silent change semantics', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model;
- model.set({x: 1});
- model.on('change', function(){ assert.ok(true); });
- model.set({x: 2}, {silent: true});
- model.set({x: 1});
- });
-
- QUnit.test('nested set multiple times', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model();
- model.on('change:b', function() {
- assert.ok(true);
- });
- model.on('change:a', function() {
- model.set({b: true});
- model.set({b: true});
- });
- model.set({a: true});
- });
-
- QUnit.test('#1122 - clear does not alter options.', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model();
- var options = {};
- model.clear(options);
- assert.ok(!options.unset);
- });
-
- QUnit.test('#1122 - unset does not alter options.', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model();
- var options = {};
- model.unset('x', options);
- assert.ok(!options.unset);
- });
-
- QUnit.test('#1355 - `options` is passed to success callbacks', function(assert) {
- assert.expect(3);
- var model = new Backbone.Model();
- var opts = {
- success: function( m, resp, options ) {
- assert.ok(options);
- }
- };
- model.sync = function(method, m, options) {
- options.success();
- };
- model.save({id: 1}, opts);
- model.fetch(opts);
- model.destroy(opts);
- });
-
- QUnit.test("#1412 - Trigger 'sync' event.", function(assert) {
- assert.expect(3);
- var model = new Backbone.Model({id: 1});
- model.sync = function(method, m, options) { options.success(); };
- model.on('sync', function(){ assert.ok(true); });
- model.fetch();
- model.save();
- model.destroy();
- });
-
- QUnit.test('#1365 - Destroy: New models execute success callback.', function(assert) {
- var done = assert.async();
- assert.expect(2);
- new Backbone.Model()
- .on('sync', function() { assert.ok(false); })
- .on('destroy', function(){ assert.ok(true); })
- .destroy({success: function(){
- assert.ok(true);
- done();
- }});
- });
-
- QUnit.test('#1433 - Save: An invalid model cannot be persisted.', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model;
- model.validate = function(){ return 'invalid'; };
- model.sync = function(){ assert.ok(false); };
- assert.strictEqual(model.save(), false);
- });
-
- QUnit.test("#1377 - Save without attrs triggers 'error'.", function(assert) {
- assert.expect(1);
- var Model = Backbone.Model.extend({
- url: '/test/',
- sync: function(method, m, options){ options.success(); },
- validate: function(){ return 'invalid'; }
- });
- var model = new Model({id: 1});
- model.on('invalid', function(){ assert.ok(true); });
- model.save();
- });
-
- QUnit.test('#1545 - `undefined` can be passed to a model constructor without coersion', function(assert) {
- var Model = Backbone.Model.extend({
- defaults: {one: 1},
- initialize: function(attrs, opts) {
- assert.equal(attrs, undefined);
- }
- });
- var emptyattrs = new Model();
- var undefinedattrs = new Model(undefined);
- });
-
- QUnit.test('#1478 - Model `save` does not trigger change on unchanged attributes', function(assert) {
- var done = assert.async();
- assert.expect(0);
- var Model = Backbone.Model.extend({
- sync: function(method, m, options) {
- setTimeout(function(){
- options.success();
- done();
- }, 0);
- }
- });
- new Model({x: true})
- .on('change:x', function(){ assert.ok(false); })
- .save(null, {wait: true});
- });
-
- QUnit.test('#1664 - Changing from one value, silently to another, back to original triggers a change.', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model({x: 1});
- model.on('change:x', function() { assert.ok(true); });
- model.set({x: 2}, {silent: true});
- model.set({x: 3}, {silent: true});
- model.set({x: 1});
- });
-
- QUnit.test('#1664 - multiple silent changes nested inside a change event', function(assert) {
- assert.expect(2);
- var changes = [];
- var model = new Backbone.Model();
- model.on('change', function() {
- model.set({a: 'c'}, {silent: true});
- model.set({b: 2}, {silent: true});
- model.unset('c', {silent: true});
- });
- model.on('change:a change:b change:c', function(m, val) { changes.push(val); });
- model.set({a: 'a', b: 1, c: 'item'});
- assert.deepEqual(changes, ['a', 1, 'item']);
- assert.deepEqual(model.attributes, {a: 'c', b: 2});
- });
-
- QUnit.test('#1791 - `attributes` is available for `parse`', function(assert) {
- var Model = Backbone.Model.extend({
- parse: function() { this.has('a'); } // shouldn't throw an error
- });
- var model = new Model(null, {parse: true});
- assert.expect(0);
- });
-
- QUnit.test('silent changes in last `change` event back to original triggers change', function(assert) {
- assert.expect(2);
- var changes = [];
- var model = new Backbone.Model();
- model.on('change:a change:b change:c', function(m, val) { changes.push(val); });
- model.on('change', function() {
- model.set({a: 'c'}, {silent: true});
- });
- model.set({a: 'a'});
- assert.deepEqual(changes, ['a']);
- model.set({a: 'a'});
- assert.deepEqual(changes, ['a', 'a']);
- });
-
- QUnit.test('#1943 change calculations should use _.isEqual', function(assert) {
- var model = new Backbone.Model({a: {key: 'value'}});
- model.set('a', {key: 'value'}, {silent: true});
- assert.equal(model.changedAttributes(), false);
- });
-
- QUnit.test('#1964 - final `change` event is always fired, regardless of interim changes', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model();
- model.on('change:property', function() {
- model.set('property', 'bar');
- });
- model.on('change', function() {
- assert.ok(true);
- });
- model.set('property', 'foo');
- });
-
- QUnit.test('isValid', function(assert) {
- var model = new Backbone.Model({valid: true});
- model.validate = function(attrs) {
- if (!attrs.valid) return 'invalid';
- };
- assert.equal(model.isValid(), true);
- assert.equal(model.set({valid: false}, {validate: true}), false);
- assert.equal(model.isValid(), true);
- model.set({valid: false});
- assert.equal(model.isValid(), false);
- assert.ok(!model.set('valid', false, {validate: true}));
- });
-
- QUnit.test('#1179 - isValid returns true in the absence of validate.', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model();
- model.validate = null;
- assert.ok(model.isValid());
- });
-
- QUnit.test('#1961 - Creating a model with {validate:true} will call validate and use the error callback', function(assert) {
- var Model = Backbone.Model.extend({
- validate: function(attrs) {
- if (attrs.id === 1) return "This shouldn't happen";
- }
- });
- var model = new Model({id: 1}, {validate: true});
- assert.equal(model.validationError, "This shouldn't happen");
- });
-
- QUnit.test('toJSON receives attrs during save(..., {wait: true})', function(assert) {
- assert.expect(1);
- var Model = Backbone.Model.extend({
- url: '/test',
- toJSON: function() {
- assert.strictEqual(this.attributes.x, 1);
- return _.clone(this.attributes);
- }
- });
- var model = new Model;
- model.save({x: 1}, {wait: true});
- });
-
- QUnit.test('#2034 - nested set with silent only triggers one change', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model();
- model.on('change', function() {
- model.set({b: true}, {silent: true});
- assert.ok(true);
- });
- model.set({a: true});
- });
-
- QUnit.test('#3778 - id will only be updated if it is set', function(assert) {
- assert.expect(2);
- var model = new Backbone.Model({id: 1});
- model.id = 2;
- model.set({foo: 'bar'});
- assert.equal(model.id, 2);
- model.set({id: 3});
- assert.equal(model.id, 3);
- });
-
-})();
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/noconflict.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/noconflict.js
deleted file mode 100644
index 9968f688..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/noconflict.js
+++ /dev/null
@@ -1,13 +0,0 @@
-(function() {
-
- QUnit.module('Backbone.noConflict');
-
- QUnit.test('noConflict', function(assert) {
- assert.expect(2);
- var noconflictBackbone = Backbone.noConflict();
- assert.equal(window.Backbone, undefined, 'Returned window.Backbone');
- window.Backbone = noconflictBackbone;
- assert.equal(window.Backbone, noconflictBackbone, 'Backbone is still pointing to the original Backbone');
- });
-
-})();
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/router.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/router.js
deleted file mode 100644
index 13110c45..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/router.js
+++ /dev/null
@@ -1,1062 +0,0 @@
-(function() {
-
- var router = null;
- var location = null;
- var lastRoute = null;
- var lastArgs = [];
-
- var onRoute = function(routerParam, route, args) {
- lastRoute = route;
- lastArgs = args;
- };
-
- var Location = function(href) {
- this.replace(href);
- };
-
- _.extend(Location.prototype, {
-
- parser: document.createElement('a'),
-
- replace: function(href) {
- this.parser.href = href;
- _.extend(this, _.pick(this.parser,
- 'href',
- 'hash',
- 'host',
- 'search',
- 'fragment',
- 'pathname',
- 'protocol'
- ));
- // In IE, anchor.pathname does not contain a leading slash though
- // window.location.pathname does.
- if (!/^\//.test(this.pathname)) this.pathname = '/' + this.pathname;
- },
-
- toString: function() {
- return this.href;
- }
-
- });
-
- QUnit.module('Backbone.Router', {
-
- setup: function() {
- location = new Location('http://example.com');
- Backbone.history = _.extend(new Backbone.History, {location: location});
- router = new Router({testing: 101});
- Backbone.history.interval = 9;
- Backbone.history.start({pushState: false});
- lastRoute = null;
- lastArgs = [];
- Backbone.history.on('route', onRoute);
- },
-
- teardown: function() {
- Backbone.history.stop();
- Backbone.history.off('route', onRoute);
- }
-
- });
-
- var ExternalObject = {
- value: 'unset',
-
- routingFunction: function(value) {
- this.value = value;
- }
- };
- ExternalObject.routingFunction = _.bind(ExternalObject.routingFunction, ExternalObject);
-
- var Router = Backbone.Router.extend({
-
- count: 0,
-
- routes: {
- 'noCallback': 'noCallback',
- 'counter': 'counter',
- 'search/:query': 'search',
- 'search/:query/p:page': 'search',
- 'charñ': 'charUTF',
- 'char%C3%B1': 'charEscaped',
- 'contacts': 'contacts',
- 'contacts/new': 'newContact',
- 'contacts/:id': 'loadContact',
- 'route-event/:arg': 'routeEvent',
- 'optional(/:item)': 'optionalItem',
- 'named/optional/(y:z)': 'namedOptional',
- 'splat/*args/end': 'splat',
- ':repo/compare/*from...*to': 'github',
- 'decode/:named/*splat': 'decode',
- '*first/complex-*part/*rest': 'complex',
- 'query/:entity': 'query',
- 'function/:value': ExternalObject.routingFunction,
- '*anything': 'anything'
- },
-
- initialize: function(options) {
- this.testing = options.testing;
- this.route('implicit', 'implicit');
- },
-
- counter: function() {
- this.count++;
- },
-
- implicit: function() {
- this.count++;
- },
-
- search: function(query, page) {
- this.query = query;
- this.page = page;
- },
-
- charUTF: function() {
- this.charType = 'UTF';
- },
-
- charEscaped: function() {
- this.charType = 'escaped';
- },
-
- contacts: function(){
- this.contact = 'index';
- },
-
- newContact: function(){
- this.contact = 'new';
- },
-
- loadContact: function(){
- this.contact = 'load';
- },
-
- optionalItem: function(arg){
- this.arg = arg !== void 0 ? arg : null;
- },
-
- splat: function(args) {
- this.args = args;
- },
-
- github: function(repo, from, to) {
- this.repo = repo;
- this.from = from;
- this.to = to;
- },
-
- complex: function(first, part, rest) {
- this.first = first;
- this.part = part;
- this.rest = rest;
- },
-
- query: function(entity, args) {
- this.entity = entity;
- this.queryArgs = args;
- },
-
- anything: function(whatever) {
- this.anything = whatever;
- },
-
- namedOptional: function(z) {
- this.z = z;
- },
-
- decode: function(named, path) {
- this.named = named;
- this.path = path;
- },
-
- routeEvent: function(arg) {
- }
-
- });
-
- QUnit.test('initialize', function(assert) {
- assert.expect(1);
- assert.equal(router.testing, 101);
- });
-
- QUnit.test('routes (simple)', function(assert) {
- assert.expect(4);
- location.replace('http://example.com#search/news');
- Backbone.history.checkUrl();
- assert.equal(router.query, 'news');
- assert.equal(router.page, void 0);
- assert.equal(lastRoute, 'search');
- assert.equal(lastArgs[0], 'news');
- });
-
- QUnit.test('routes (simple, but unicode)', function(assert) {
- assert.expect(4);
- location.replace('http://example.com#search/тест');
- Backbone.history.checkUrl();
- assert.equal(router.query, 'тест');
- assert.equal(router.page, void 0);
- assert.equal(lastRoute, 'search');
- assert.equal(lastArgs[0], 'тест');
- });
-
- QUnit.test('routes (two part)', function(assert) {
- assert.expect(2);
- location.replace('http://example.com#search/nyc/p10');
- Backbone.history.checkUrl();
- assert.equal(router.query, 'nyc');
- assert.equal(router.page, '10');
- });
-
- QUnit.test('routes via navigate', function(assert) {
- assert.expect(2);
- Backbone.history.navigate('search/manhattan/p20', {trigger: true});
- assert.equal(router.query, 'manhattan');
- assert.equal(router.page, '20');
- });
-
- QUnit.test('routes via navigate with params', function(assert) {
- assert.expect(1);
- Backbone.history.navigate('query/test?a=b', {trigger: true});
- assert.equal(router.queryArgs, 'a=b');
- });
-
- QUnit.test('routes via navigate for backwards-compatibility', function(assert) {
- assert.expect(2);
- Backbone.history.navigate('search/manhattan/p20', true);
- assert.equal(router.query, 'manhattan');
- assert.equal(router.page, '20');
- });
-
- QUnit.test('reports matched route via nagivate', function(assert) {
- assert.expect(1);
- assert.ok(Backbone.history.navigate('search/manhattan/p20', true));
- });
-
- QUnit.test('route precedence via navigate', function(assert){
- assert.expect(6);
- // check both 0.9.x and backwards-compatibility options
- _.each([{trigger: true}, true], function( options ){
- Backbone.history.navigate('contacts', options);
- assert.equal(router.contact, 'index');
- Backbone.history.navigate('contacts/new', options);
- assert.equal(router.contact, 'new');
- Backbone.history.navigate('contacts/foo', options);
- assert.equal(router.contact, 'load');
- });
- });
-
- QUnit.test('loadUrl is not called for identical routes.', function(assert) {
- assert.expect(0);
- Backbone.history.loadUrl = function(){ assert.ok(false); };
- location.replace('http://example.com#route');
- Backbone.history.navigate('route');
- Backbone.history.navigate('/route');
- Backbone.history.navigate('/route');
- });
-
- QUnit.test('use implicit callback if none provided', function(assert) {
- assert.expect(1);
- router.count = 0;
- router.navigate('implicit', {trigger: true});
- assert.equal(router.count, 1);
- });
-
- QUnit.test('routes via navigate with {replace: true}', function(assert) {
- assert.expect(1);
- location.replace('http://example.com#start_here');
- Backbone.history.checkUrl();
- location.replace = function(href) {
- assert.strictEqual(href, new Location('http://example.com#end_here').href);
- };
- Backbone.history.navigate('end_here', {replace: true});
- });
-
- QUnit.test('routes (splats)', function(assert) {
- assert.expect(1);
- location.replace('http://example.com#splat/long-list/of/splatted_99args/end');
- Backbone.history.checkUrl();
- assert.equal(router.args, 'long-list/of/splatted_99args');
- });
-
- QUnit.test('routes (github)', function(assert) {
- assert.expect(3);
- location.replace('http://example.com#backbone/compare/1.0...braddunbar:with/slash');
- Backbone.history.checkUrl();
- assert.equal(router.repo, 'backbone');
- assert.equal(router.from, '1.0');
- assert.equal(router.to, 'braddunbar:with/slash');
- });
-
- QUnit.test('routes (optional)', function(assert) {
- assert.expect(2);
- location.replace('http://example.com#optional');
- Backbone.history.checkUrl();
- assert.ok(!router.arg);
- location.replace('http://example.com#optional/thing');
- Backbone.history.checkUrl();
- assert.equal(router.arg, 'thing');
- });
-
- QUnit.test('routes (complex)', function(assert) {
- assert.expect(3);
- location.replace('http://example.com#one/two/three/complex-part/four/five/six/seven');
- Backbone.history.checkUrl();
- assert.equal(router.first, 'one/two/three');
- assert.equal(router.part, 'part');
- assert.equal(router.rest, 'four/five/six/seven');
- });
-
- QUnit.test('routes (query)', function(assert) {
- assert.expect(5);
- location.replace('http://example.com#query/mandel?a=b&c=d');
- Backbone.history.checkUrl();
- assert.equal(router.entity, 'mandel');
- assert.equal(router.queryArgs, 'a=b&c=d');
- assert.equal(lastRoute, 'query');
- assert.equal(lastArgs[0], 'mandel');
- assert.equal(lastArgs[1], 'a=b&c=d');
- });
-
- QUnit.test('routes (anything)', function(assert) {
- assert.expect(1);
- location.replace('http://example.com#doesnt-match-a-route');
- Backbone.history.checkUrl();
- assert.equal(router.anything, 'doesnt-match-a-route');
- });
-
- QUnit.test('routes (function)', function(assert) {
- assert.expect(3);
- router.on('route', function(name) {
- assert.ok(name === '');
- });
- assert.equal(ExternalObject.value, 'unset');
- location.replace('http://example.com#function/set');
- Backbone.history.checkUrl();
- assert.equal(ExternalObject.value, 'set');
- });
-
- QUnit.test('Decode named parameters, not splats.', function(assert) {
- assert.expect(2);
- location.replace('http://example.com#decode/a%2Fb/c%2Fd/e');
- Backbone.history.checkUrl();
- assert.strictEqual(router.named, 'a/b');
- assert.strictEqual(router.path, 'c/d/e');
- });
-
- QUnit.test("fires event when router doesn't have callback on it", function(assert) {
- assert.expect(1);
- router.on('route:noCallback', function(){ assert.ok(true); });
- location.replace('http://example.com#noCallback');
- Backbone.history.checkUrl();
- });
-
- QUnit.test('No events are triggered if #execute returns false.', function(assert) {
- assert.expect(1);
- var MyRouter = Backbone.Router.extend({
-
- routes: {
- foo: function() {
- assert.ok(true);
- }
- },
-
- execute: function(callback, args) {
- callback.apply(this, args);
- return false;
- }
-
- });
-
- var myRouter = new MyRouter;
-
- myRouter.on('route route:foo', function() {
- assert.ok(false);
- });
-
- Backbone.history.on('route', function() {
- assert.ok(false);
- });
-
- location.replace('http://example.com#foo');
- Backbone.history.checkUrl();
- });
-
- QUnit.test('#933, #908 - leading slash', function(assert) {
- assert.expect(2);
- location.replace('http://example.com/root/foo');
-
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {location: location});
- Backbone.history.start({root: '/root', hashChange: false, silent: true});
- assert.strictEqual(Backbone.history.getFragment(), 'foo');
-
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {location: location});
- Backbone.history.start({root: '/root/', hashChange: false, silent: true});
- assert.strictEqual(Backbone.history.getFragment(), 'foo');
- });
-
- QUnit.test('#967 - Route callback gets passed encoded values.', function(assert) {
- assert.expect(3);
- var route = 'has%2Fslash/complex-has%23hash/has%20space';
- Backbone.history.navigate(route, {trigger: true});
- assert.strictEqual(router.first, 'has/slash');
- assert.strictEqual(router.part, 'has#hash');
- assert.strictEqual(router.rest, 'has space');
- });
-
- QUnit.test('correctly handles URLs with % (#868)', function(assert) {
- assert.expect(3);
- location.replace('http://example.com#search/fat%3A1.5%25');
- Backbone.history.checkUrl();
- location.replace('http://example.com#search/fat');
- Backbone.history.checkUrl();
- assert.equal(router.query, 'fat');
- assert.equal(router.page, void 0);
- assert.equal(lastRoute, 'search');
- });
-
- QUnit.test('#2666 - Hashes with UTF8 in them.', function(assert) {
- assert.expect(2);
- Backbone.history.navigate('charñ', {trigger: true});
- assert.equal(router.charType, 'UTF');
- Backbone.history.navigate('char%C3%B1', {trigger: true});
- assert.equal(router.charType, 'UTF');
- });
-
- QUnit.test('#1185 - Use pathname when hashChange is not wanted.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com/path/name#hash');
- Backbone.history = _.extend(new Backbone.History, {location: location});
- Backbone.history.start({hashChange: false});
- var fragment = Backbone.history.getFragment();
- assert.strictEqual(fragment, location.pathname.replace(/^\//, ''));
- });
-
- QUnit.test('#1206 - Strip leading slash before location.assign.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com/root/');
- Backbone.history = _.extend(new Backbone.History, {location: location});
- Backbone.history.start({hashChange: false, root: '/root/'});
- location.assign = function(pathname) {
- assert.strictEqual(pathname, '/root/fragment');
- };
- Backbone.history.navigate('/fragment');
- });
-
- QUnit.test('#1387 - Root fragment without trailing slash.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com/root');
- Backbone.history = _.extend(new Backbone.History, {location: location});
- Backbone.history.start({hashChange: false, root: '/root/', silent: true});
- assert.strictEqual(Backbone.history.getFragment(), '');
- });
-
- QUnit.test('#1366 - History does not prepend root to fragment.', function(assert) {
- assert.expect(2);
- Backbone.history.stop();
- location.replace('http://example.com/root/');
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(state, title, url) {
- assert.strictEqual(url, '/root/x');
- }
- }
- });
- Backbone.history.start({
- root: '/root/',
- pushState: true,
- hashChange: false
- });
- Backbone.history.navigate('x');
- assert.strictEqual(Backbone.history.fragment, 'x');
- });
-
- QUnit.test('Normalize root.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com/root');
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(state, title, url) {
- assert.strictEqual(url, '/root/fragment');
- }
- }
- });
- Backbone.history.start({
- pushState: true,
- root: '/root',
- hashChange: false
- });
- Backbone.history.navigate('fragment');
- });
-
- QUnit.test('Normalize root.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com/root#fragment');
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(state, title, url) {},
- replaceState: function(state, title, url) {
- assert.strictEqual(url, '/root/fragment');
- }
- }
- });
- Backbone.history.start({
- pushState: true,
- root: '/root'
- });
- });
-
- QUnit.test('Normalize root.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com/root');
- Backbone.history = _.extend(new Backbone.History, {location: location});
- Backbone.history.loadUrl = function() { assert.ok(true); };
- Backbone.history.start({
- pushState: true,
- root: '/root'
- });
- });
-
- QUnit.test('Normalize root - leading slash.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com/root');
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(){},
- replaceState: function(){}
- }
- });
- Backbone.history.start({root: 'root'});
- assert.strictEqual(Backbone.history.root, '/root/');
- });
-
- QUnit.test('Transition from hashChange to pushState.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com/root#x/y');
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(){},
- replaceState: function(state, title, url){
- assert.strictEqual(url, '/root/x/y');
- }
- }
- });
- Backbone.history.start({
- root: 'root',
- pushState: true
- });
- });
-
- QUnit.test('#1619: Router: Normalize empty root', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com/');
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(){},
- replaceState: function(){}
- }
- });
- Backbone.history.start({root: ''});
- assert.strictEqual(Backbone.history.root, '/');
- });
-
- QUnit.test('#1619: Router: nagivate with empty root', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com/');
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(state, title, url) {
- assert.strictEqual(url, '/fragment');
- }
- }
- });
- Backbone.history.start({
- pushState: true,
- root: '',
- hashChange: false
- });
- Backbone.history.navigate('fragment');
- });
-
- QUnit.test('Transition from pushState to hashChange.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com/root/x/y?a=b');
- location.replace = function(url) {
- assert.strictEqual(url, '/root#x/y?a=b');
- };
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: null,
- replaceState: null
- }
- });
- Backbone.history.start({
- root: 'root',
- pushState: true
- });
- });
-
- QUnit.test('#1695 - hashChange to pushState with search.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com/root#x/y?a=b');
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(){},
- replaceState: function(state, title, url){
- assert.strictEqual(url, '/root/x/y?a=b');
- }
- }
- });
- Backbone.history.start({
- root: 'root',
- pushState: true
- });
- });
-
- QUnit.test('#1746 - Router allows empty route.', function(assert) {
- assert.expect(1);
- var MyRouter = Backbone.Router.extend({
- routes: {'': 'empty'},
- empty: function(){},
- route: function(route){
- assert.strictEqual(route, '');
- }
- });
- new MyRouter;
- });
-
- QUnit.test('#1794 - Trailing space in fragments.', function(assert) {
- assert.expect(1);
- var history = new Backbone.History;
- assert.strictEqual(history.getFragment('fragment '), 'fragment');
- });
-
- QUnit.test('#1820 - Leading slash and trailing space.', 1, function(assert) {
- var history = new Backbone.History;
- assert.strictEqual(history.getFragment('/fragment '), 'fragment');
- });
-
- QUnit.test('#1980 - Optional parameters.', function(assert) {
- assert.expect(2);
- location.replace('http://example.com#named/optional/y');
- Backbone.history.checkUrl();
- assert.strictEqual(router.z, undefined);
- location.replace('http://example.com#named/optional/y123');
- Backbone.history.checkUrl();
- assert.strictEqual(router.z, '123');
- });
-
- QUnit.test("#2062 - Trigger 'route' event on router instance.", function(assert) {
- assert.expect(2);
- router.on('route', function(name, args) {
- assert.strictEqual(name, 'routeEvent');
- assert.deepEqual(args, ['x', null]);
- });
- location.replace('http://example.com#route-event/x');
- Backbone.history.checkUrl();
- });
-
- QUnit.test('#2255 - Extend routes by making routes a function.', function(assert) {
- assert.expect(1);
- var RouterBase = Backbone.Router.extend({
- routes: function() {
- return {
- home: 'root',
- index: 'index.html'
- };
- }
- });
-
- var RouterExtended = RouterBase.extend({
- routes: function() {
- var _super = RouterExtended.__super__.routes;
- return _.extend(_super(), {show: 'show', search: 'search'});
- }
- });
-
- var myRouter = new RouterExtended();
- assert.deepEqual({home: 'root', index: 'index.html', show: 'show', search: 'search'}, myRouter.routes);
- });
-
- QUnit.test('#2538 - hashChange to pushState only if both requested.', function(assert) {
- assert.expect(0);
- Backbone.history.stop();
- location.replace('http://example.com/root?a=b#x/y');
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(){},
- replaceState: function(){ assert.ok(false); }
- }
- });
- Backbone.history.start({
- root: 'root',
- pushState: true,
- hashChange: false
- });
- });
-
- QUnit.test('No hash fallback.', function(assert) {
- assert.expect(0);
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(){},
- replaceState: function(){}
- }
- });
-
- var MyRouter = Backbone.Router.extend({
- routes: {
- hash: function() { assert.ok(false); }
- }
- });
- var myRouter = new MyRouter;
-
- location.replace('http://example.com/');
- Backbone.history.start({
- pushState: true,
- hashChange: false
- });
- location.replace('http://example.com/nomatch#hash');
- Backbone.history.checkUrl();
- });
-
- QUnit.test('#2656 - No trailing slash on root.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(state, title, url){
- assert.strictEqual(url, '/root');
- }
- }
- });
- location.replace('http://example.com/root/path');
- Backbone.history.start({pushState: true, hashChange: false, root: 'root'});
- Backbone.history.navigate('');
- });
-
- QUnit.test('#2656 - No trailing slash on root.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(state, title, url) {
- assert.strictEqual(url, '/');
- }
- }
- });
- location.replace('http://example.com/path');
- Backbone.history.start({pushState: true, hashChange: false});
- Backbone.history.navigate('');
- });
-
- QUnit.test('#2656 - No trailing slash on root.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(state, title, url){
- assert.strictEqual(url, '/root?x=1');
- }
- }
- });
- location.replace('http://example.com/root/path');
- Backbone.history.start({pushState: true, hashChange: false, root: 'root'});
- Backbone.history.navigate('?x=1');
- });
-
- QUnit.test('#2765 - Fragment matching sans query/hash.', function(assert) {
- assert.expect(2);
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(state, title, url) {
- assert.strictEqual(url, '/path?query#hash');
- }
- }
- });
-
- var MyRouter = Backbone.Router.extend({
- routes: {
- path: function() { assert.ok(true); }
- }
- });
- var myRouter = new MyRouter;
-
- location.replace('http://example.com/');
- Backbone.history.start({pushState: true, hashChange: false});
- Backbone.history.navigate('path?query#hash', true);
- });
-
- QUnit.test('Do not decode the search params.', function(assert) {
- assert.expect(1);
- var MyRouter = Backbone.Router.extend({
- routes: {
- path: function(params){
- assert.strictEqual(params, 'x=y%3Fz');
- }
- }
- });
- var myRouter = new MyRouter;
- Backbone.history.navigate('path?x=y%3Fz', true);
- });
-
- QUnit.test('Navigate to a hash url.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {location: location});
- Backbone.history.start({pushState: true});
- var MyRouter = Backbone.Router.extend({
- routes: {
- path: function(params) {
- assert.strictEqual(params, 'x=y');
- }
- }
- });
- var myRouter = new MyRouter;
- location.replace('http://example.com/path?x=y#hash');
- Backbone.history.checkUrl();
- });
-
- QUnit.test('#navigate to a hash url.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {location: location});
- Backbone.history.start({pushState: true});
- var MyRouter = Backbone.Router.extend({
- routes: {
- path: function(params) {
- assert.strictEqual(params, 'x=y');
- }
- }
- });
- var myRouter = new MyRouter;
- Backbone.history.navigate('path?x=y#hash', true);
- });
-
- QUnit.test('unicode pathname', function(assert) {
- assert.expect(1);
- location.replace('http://example.com/myyjä');
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {location: location});
- var MyRouter = Backbone.Router.extend({
- routes: {
- myyjä: function() {
- assert.ok(true);
- }
- }
- });
- new MyRouter;
- Backbone.history.start({pushState: true});
- });
-
- QUnit.test('unicode pathname with % in a parameter', function(assert) {
- assert.expect(1);
- location.replace('http://example.com/myyjä/foo%20%25%3F%2f%40%25%20bar');
- location.pathname = '/myyj%C3%A4/foo%20%25%3F%2f%40%25%20bar';
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {location: location});
- var MyRouter = Backbone.Router.extend({
- routes: {
- 'myyjä/:query': function(query) {
- assert.strictEqual(query, 'foo %?/@% bar');
- }
- }
- });
- new MyRouter;
- Backbone.history.start({pushState: true});
- });
-
- QUnit.test('newline in route', function(assert) {
- assert.expect(1);
- location.replace('http://example.com/stuff%0Anonsense?param=foo%0Abar');
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {location: location});
- var MyRouter = Backbone.Router.extend({
- routes: {
- 'stuff\nnonsense': function() {
- assert.ok(true);
- }
- }
- });
- new MyRouter;
- Backbone.history.start({pushState: true});
- });
-
- QUnit.test('Router#execute receives callback, args, name.', function(assert) {
- assert.expect(3);
- location.replace('http://example.com#foo/123/bar?x=y');
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {location: location});
- var MyRouter = Backbone.Router.extend({
- routes: {'foo/:id/bar': 'foo'},
- foo: function(){},
- execute: function(callback, args, name) {
- assert.strictEqual(callback, this.foo);
- assert.deepEqual(args, ['123', 'x=y']);
- assert.strictEqual(name, 'foo');
- }
- });
- var myRouter = new MyRouter;
- Backbone.history.start();
- });
-
- QUnit.test('pushState to hashChange with only search params.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com?a=b');
- location.replace = function(url) {
- assert.strictEqual(url, '/#?a=b');
- };
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: null
- });
- Backbone.history.start({pushState: true});
- });
-
- QUnit.test('#3123 - History#navigate decodes before comparison.', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com/shop/search?keyword=short%20dress');
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: function(){ assert.ok(false); },
- replaceState: function(){ assert.ok(false); }
- }
- });
- Backbone.history.start({pushState: true});
- Backbone.history.navigate('shop/search?keyword=short%20dress', true);
- assert.strictEqual(Backbone.history.fragment, 'shop/search?keyword=short dress');
- });
-
- QUnit.test('#3175 - Urls in the params', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com#login?a=value&backUrl=https%3A%2F%2Fwww.msn.com%2Fidp%2Fidpdemo%3Fspid%3Dspdemo%26target%3Db');
- Backbone.history = _.extend(new Backbone.History, {location: location});
- var myRouter = new Backbone.Router;
- myRouter.route('login', function(params) {
- assert.strictEqual(params, 'a=value&backUrl=https%3A%2F%2Fwww.msn.com%2Fidp%2Fidpdemo%3Fspid%3Dspdemo%26target%3Db');
- });
- Backbone.history.start();
- });
-
- QUnit.test('#3358 - pushState to hashChange transition with search params', function(assert) {
- assert.expect(1);
- Backbone.history.stop();
- location.replace('http://example.com/root?foo=bar');
- location.replace = function(url) {
- assert.strictEqual(url, '/root#?foo=bar');
- };
- Backbone.history = _.extend(new Backbone.History, {
- location: location,
- history: {
- pushState: undefined,
- replaceState: undefined
- }
- });
- Backbone.history.start({root: '/root', pushState: true});
- });
-
- QUnit.test("Paths that don't match the root should not match no root", function(assert) {
- assert.expect(0);
- location.replace('http://example.com/foo');
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {location: location});
- var MyRouter = Backbone.Router.extend({
- routes: {
- foo: function(){
- assert.ok(false, 'should not match unless root matches');
- }
- }
- });
- var myRouter = new MyRouter;
- Backbone.history.start({root: 'root', pushState: true});
- });
-
- QUnit.test("Paths that don't match the root should not match roots of the same length", function(assert) {
- assert.expect(0);
- location.replace('http://example.com/xxxx/foo');
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {location: location});
- var MyRouter = Backbone.Router.extend({
- routes: {
- foo: function(){
- assert.ok(false, 'should not match unless root matches');
- }
- }
- });
- var myRouter = new MyRouter;
- Backbone.history.start({root: 'root', pushState: true});
- });
-
- QUnit.test('roots with regex characters', function(assert) {
- assert.expect(1);
- location.replace('http://example.com/x+y.z/foo');
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {location: location});
- var MyRouter = Backbone.Router.extend({
- routes: {foo: function(){ assert.ok(true); }}
- });
- var myRouter = new MyRouter;
- Backbone.history.start({root: 'x+y.z', pushState: true});
- });
-
- QUnit.test('roots with unicode characters', function(assert) {
- assert.expect(1);
- location.replace('http://example.com/®ooτ/foo');
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {location: location});
- var MyRouter = Backbone.Router.extend({
- routes: {foo: function(){ assert.ok(true); }}
- });
- var myRouter = new MyRouter;
- Backbone.history.start({root: '®ooτ', pushState: true});
- });
-
- QUnit.test('roots without slash', function(assert) {
- assert.expect(1);
- location.replace('http://example.com/®ooτ');
- Backbone.history.stop();
- Backbone.history = _.extend(new Backbone.History, {location: location});
- var MyRouter = Backbone.Router.extend({
- routes: {'': function(){ assert.ok(true); }}
- });
- var myRouter = new MyRouter;
- Backbone.history.start({root: '®ooτ', pushState: true});
- });
-
-})();
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/setup/dom-setup.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/setup/dom-setup.js
deleted file mode 100644
index f2242282..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/setup/dom-setup.js
+++ /dev/null
@@ -1,4 +0,0 @@
-$('body').append(
- '<div id="qunit"></div>' +
- '<div id="qunit-fixture"></div>'
-);
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/setup/environment.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/setup/environment.js
deleted file mode 100644
index c2441ac7..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/setup/environment.js
+++ /dev/null
@@ -1,45 +0,0 @@
-(function() {
-
- var sync = Backbone.sync;
- var ajax = Backbone.ajax;
- var emulateHTTP = Backbone.emulateHTTP;
- var emulateJSON = Backbone.emulateJSON;
- var history = window.history;
- var pushState = history.pushState;
- var replaceState = history.replaceState;
-
- QUnit.config.noglobals = true;
-
- QUnit.testStart(function() {
- var env = QUnit.config.current.testEnvironment;
-
- // We never want to actually call these during tests.
- history.pushState = history.replaceState = function(){};
-
- // Capture ajax settings for comparison.
- Backbone.ajax = function(settings) {
- env.ajaxSettings = settings;
- };
-
- // Capture the arguments to Backbone.sync for comparison.
- Backbone.sync = function(method, model, options) {
- env.syncArgs = {
- method: method,
- model: model,
- options: options
- };
- sync.apply(this, arguments);
- };
-
- });
-
- QUnit.testDone(function() {
- Backbone.sync = sync;
- Backbone.ajax = ajax;
- Backbone.emulateHTTP = emulateHTTP;
- Backbone.emulateJSON = emulateJSON;
- history.pushState = pushState;
- history.replaceState = replaceState;
- });
-
-})();
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/sync.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/sync.js
deleted file mode 100644
index 8813f158..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/sync.js
+++ /dev/null
@@ -1,239 +0,0 @@
-(function() {
-
- var Library = Backbone.Collection.extend({
- url: function() { return '/library'; }
- });
- var library;
-
- var attrs = {
- title: 'The Tempest',
- author: 'Bill Shakespeare',
- length: 123
- };
-
- QUnit.module('Backbone.sync', {
-
- beforeEach: function(assert) {
- library = new Library;
- library.create(attrs, {wait: false});
- },
-
- afterEach: function(assert) {
- Backbone.emulateHTTP = false;
- }
-
- });
-
- QUnit.test('read', function(assert) {
- assert.expect(4);
- library.fetch();
- assert.equal(this.ajaxSettings.url, '/library');
- assert.equal(this.ajaxSettings.type, 'GET');
- assert.equal(this.ajaxSettings.dataType, 'json');
- assert.ok(_.isEmpty(this.ajaxSettings.data));
- });
-
- QUnit.test('passing data', function(assert) {
- assert.expect(3);
- library.fetch({data: {a: 'a', one: 1}});
- assert.equal(this.ajaxSettings.url, '/library');
- assert.equal(this.ajaxSettings.data.a, 'a');
- assert.equal(this.ajaxSettings.data.one, 1);
- });
-
- QUnit.test('create', function(assert) {
- assert.expect(6);
- assert.equal(this.ajaxSettings.url, '/library');
- assert.equal(this.ajaxSettings.type, 'POST');
- assert.equal(this.ajaxSettings.dataType, 'json');
- var data = JSON.parse(this.ajaxSettings.data);
- assert.equal(data.title, 'The Tempest');
- assert.equal(data.author, 'Bill Shakespeare');
- assert.equal(data.length, 123);
- });
-
- QUnit.test('update', function(assert) {
- assert.expect(7);
- library.first().save({id: '1-the-tempest', author: 'William Shakespeare'});
- assert.equal(this.ajaxSettings.url, '/library/1-the-tempest');
- assert.equal(this.ajaxSettings.type, 'PUT');
- assert.equal(this.ajaxSettings.dataType, 'json');
- var data = JSON.parse(this.ajaxSettings.data);
- assert.equal(data.id, '1-the-tempest');
- assert.equal(data.title, 'The Tempest');
- assert.equal(data.author, 'William Shakespeare');
- assert.equal(data.length, 123);
- });
-
- QUnit.test('update with emulateHTTP and emulateJSON', function(assert) {
- assert.expect(7);
- library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
- emulateHTTP: true,
- emulateJSON: true
- });
- assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
- assert.equal(this.ajaxSettings.type, 'POST');
- assert.equal(this.ajaxSettings.dataType, 'json');
- assert.equal(this.ajaxSettings.data._method, 'PUT');
- var data = JSON.parse(this.ajaxSettings.data.model);
- assert.equal(data.id, '2-the-tempest');
- assert.equal(data.author, 'Tim Shakespeare');
- assert.equal(data.length, 123);
- });
-
- QUnit.test('update with just emulateHTTP', function(assert) {
- assert.expect(6);
- library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
- emulateHTTP: true
- });
- assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
- assert.equal(this.ajaxSettings.type, 'POST');
- assert.equal(this.ajaxSettings.contentType, 'application/json');
- var data = JSON.parse(this.ajaxSettings.data);
- assert.equal(data.id, '2-the-tempest');
- assert.equal(data.author, 'Tim Shakespeare');
- assert.equal(data.length, 123);
- });
-
- QUnit.test('update with just emulateJSON', function(assert) {
- assert.expect(6);
- library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
- emulateJSON: true
- });
- assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
- assert.equal(this.ajaxSettings.type, 'PUT');
- assert.equal(this.ajaxSettings.contentType, 'application/x-www-form-urlencoded');
- var data = JSON.parse(this.ajaxSettings.data.model);
- assert.equal(data.id, '2-the-tempest');
- assert.equal(data.author, 'Tim Shakespeare');
- assert.equal(data.length, 123);
- });
-
- QUnit.test('read model', function(assert) {
- assert.expect(3);
- library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
- library.first().fetch();
- assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
- assert.equal(this.ajaxSettings.type, 'GET');
- assert.ok(_.isEmpty(this.ajaxSettings.data));
- });
-
- QUnit.test('destroy', function(assert) {
- assert.expect(3);
- library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
- library.first().destroy({wait: true});
- assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
- assert.equal(this.ajaxSettings.type, 'DELETE');
- assert.equal(this.ajaxSettings.data, null);
- });
-
- QUnit.test('destroy with emulateHTTP', function(assert) {
- assert.expect(3);
- library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
- library.first().destroy({
- emulateHTTP: true,
- emulateJSON: true
- });
- assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
- assert.equal(this.ajaxSettings.type, 'POST');
- assert.equal(JSON.stringify(this.ajaxSettings.data), '{"_method":"DELETE"}');
- });
-
- QUnit.test('urlError', function(assert) {
- assert.expect(2);
- var model = new Backbone.Model();
- assert.raises(function() {
- model.fetch();
- });
- model.fetch({url: '/one/two'});
- assert.equal(this.ajaxSettings.url, '/one/two');
- });
-
- QUnit.test('#1052 - `options` is optional.', function(assert) {
- assert.expect(0);
- var model = new Backbone.Model();
- model.url = '/test';
- Backbone.sync('create', model);
- });
-
- QUnit.test('Backbone.ajax', function(assert) {
- assert.expect(1);
- Backbone.ajax = function(settings){
- assert.strictEqual(settings.url, '/test');
- };
- var model = new Backbone.Model();
- model.url = '/test';
- Backbone.sync('create', model);
- });
-
- QUnit.test('Call provided error callback on error.', function(assert) {
- assert.expect(1);
- var model = new Backbone.Model;
- model.url = '/test';
- Backbone.sync('read', model, {
- error: function() { assert.ok(true); }
- });
- this.ajaxSettings.error();
- });
-
- QUnit.test('Use Backbone.emulateHTTP as default.', function(assert) {
- assert.expect(2);
- var model = new Backbone.Model;
- model.url = '/test';
-
- Backbone.emulateHTTP = true;
- model.sync('create', model);
- assert.strictEqual(this.ajaxSettings.emulateHTTP, true);
-
- Backbone.emulateHTTP = false;
- model.sync('create', model);
- assert.strictEqual(this.ajaxSettings.emulateHTTP, false);
- });
-
- QUnit.test('Use Backbone.emulateJSON as default.', function(assert) {
- assert.expect(2);
- var model = new Backbone.Model;
- model.url = '/test';
-
- Backbone.emulateJSON = true;
- model.sync('create', model);
- assert.strictEqual(this.ajaxSettings.emulateJSON, true);
-
- Backbone.emulateJSON = false;
- model.sync('create', model);
- assert.strictEqual(this.ajaxSettings.emulateJSON, false);
- });
-
- QUnit.test('#1756 - Call user provided beforeSend function.', function(assert) {
- assert.expect(4);
- Backbone.emulateHTTP = true;
- var model = new Backbone.Model;
- model.url = '/test';
- var xhr = {
- setRequestHeader: function(header, value) {
- assert.strictEqual(header, 'X-HTTP-Method-Override');
- assert.strictEqual(value, 'DELETE');
- }
- };
- model.sync('delete', model, {
- beforeSend: function(_xhr) {
- assert.ok(_xhr === xhr);
- return false;
- }
- });
- assert.strictEqual(this.ajaxSettings.beforeSend(xhr), false);
- });
-
- QUnit.test('#2928 - Pass along `textStatus` and `errorThrown`.', function(assert) {
- assert.expect(2);
- var model = new Backbone.Model;
- model.url = '/test';
- model.on('error', function(m, xhr, options) {
- assert.strictEqual(options.textStatus, 'textStatus');
- assert.strictEqual(options.errorThrown, 'errorThrown');
- });
- model.fetch();
- this.ajaxSettings.error({}, 'textStatus', 'errorThrown');
- });
-
-})();
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/view.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/view.js
deleted file mode 100644
index faf3445b..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/backbone/test/view.js
+++ /dev/null
@@ -1,495 +0,0 @@
-(function() {
-
- var view;
-
- QUnit.module('Backbone.View', {
-
- beforeEach: function(assert) {
- $('#qunit-fixture').append(
- '<div id="testElement"><h1>Test</h1></div>'
- );
-
- view = new Backbone.View({
- id: 'test-view',
- className: 'test-view',
- other: 'non-special-option'
- });
- },
-
- afterEach: function() {
- $('#testElement').remove();
- $('#test-view').remove();
- }
-
- });
-
- QUnit.test('constructor', function(assert) {
- assert.expect(3);
- assert.equal(view.el.id, 'test-view');
- assert.equal(view.el.className, 'test-view');
- assert.equal(view.el.other, void 0);
- });
-
- QUnit.test('$', function(assert) {
- assert.expect(2);
- var myView = new Backbone.View;
- myView.setElement('<p><a><b>test</b></a></p>');
- var result = myView.$('a b');
-
- assert.strictEqual(result[0].innerHTML, 'test');
- assert.ok(result.length === +result.length);
- });
-
- QUnit.test('$el', function(assert) {
- assert.expect(3);
- var myView = new Backbone.View;
- myView.setElement('<p><a><b>test</b></a></p>');
- assert.strictEqual(myView.el.nodeType, 1);
-
- assert.ok(myView.$el instanceof Backbone.$);
- assert.strictEqual(myView.$el[0], myView.el);
- });
-
- QUnit.test('initialize', function(assert) {
- assert.expect(1);
- var View = Backbone.View.extend({
- initialize: function() {
- this.one = 1;
- }
- });
-
- assert.strictEqual(new View().one, 1);
- });
-
- QUnit.test('render', function(assert) {
- assert.expect(1);
- var myView = new Backbone.View;
- assert.equal(myView.render(), myView, '#render returns the view instance');
- });
-
- QUnit.test('delegateEvents', function(assert) {
- assert.expect(6);
- var counter1 = 0, counter2 = 0;
-
- var myView = new Backbone.View({el: '#testElement'});
- myView.increment = function(){ counter1++; };
- myView.$el.on('click', function(){ counter2++; });
-
- var events = {'click h1': 'increment'};
-
- myView.delegateEvents(events);
- myView.$('h1').trigger('click');
- assert.equal(counter1, 1);
- assert.equal(counter2, 1);
-
- myView.$('h1').trigger('click');
- assert.equal(counter1, 2);
- assert.equal(counter2, 2);
-
- myView.delegateEvents(events);
- myView.$('h1').trigger('click');
- assert.equal(counter1, 3);
- assert.equal(counter2, 3);
- });
-
- QUnit.test('delegate', function(assert) {
- assert.expect(3);
- var myView = new Backbone.View({el: '#testElement'});
- myView.delegate('click', 'h1', function() {
- assert.ok(true);
- });
- myView.delegate('click', function() {
- assert.ok(true);
- });
- myView.$('h1').trigger('click');
-
- assert.equal(myView.delegate(), myView, '#delegate returns the view instance');
- });
-
- QUnit.test('delegateEvents allows functions for callbacks', function(assert) {
- assert.expect(3);
- var myView = new Backbone.View({el: '<p></p>'});
- myView.counter = 0;
-
- var events = {
- click: function() {
- this.counter++;
- }
- };
-
- myView.delegateEvents(events);
- myView.$el.trigger('click');
- assert.equal(myView.counter, 1);
-
- myView.$el.trigger('click');
- assert.equal(myView.counter, 2);
-
- myView.delegateEvents(events);
- myView.$el.trigger('click');
- assert.equal(myView.counter, 3);
- });
-
-
- QUnit.test('delegateEvents ignore undefined methods', function(assert) {
- assert.expect(0);
- var myView = new Backbone.View({el: '<p></p>'});
- myView.delegateEvents({'click': 'undefinedMethod'});
- myView.$el.trigger('click');
- });
-
- QUnit.test('undelegateEvents', function(assert) {
- assert.expect(7);
- var counter1 = 0, counter2 = 0;
-
- var myView = new Backbone.View({el: '#testElement'});
- myView.increment = function(){ counter1++; };
- myView.$el.on('click', function(){ counter2++; });
-
- var events = {'click h1': 'increment'};
-
- myView.delegateEvents(events);
- myView.$('h1').trigger('click');
- assert.equal(counter1, 1);
- assert.equal(counter2, 1);
-
- myView.undelegateEvents();
- myView.$('h1').trigger('click');
- assert.equal(counter1, 1);
- assert.equal(counter2, 2);
-
- myView.delegateEvents(events);
- myView.$('h1').trigger('click');
- assert.equal(counter1, 2);
- assert.equal(counter2, 3);
-
- assert.equal(myView.undelegateEvents(), myView, '#undelegateEvents returns the view instance');
- });
-
- QUnit.test('undelegate', function(assert) {
- assert.expect(1);
- var myView = new Backbone.View({el: '#testElement'});
- myView.delegate('click', function() { assert.ok(false); });
- myView.delegate('click', 'h1', function() { assert.ok(false); });
-
- myView.undelegate('click');
-
- myView.$('h1').trigger('click');
- myView.$el.trigger('click');
-
- assert.equal(myView.undelegate(), myView, '#undelegate returns the view instance');
- });
-
- QUnit.test('undelegate with passed handler', function(assert) {
- assert.expect(1);
- var myView = new Backbone.View({el: '#testElement'});
- var listener = function() { assert.ok(false); };
- myView.delegate('click', listener);
- myView.delegate('click', function() { assert.ok(true); });
- myView.undelegate('click', listener);
- myView.$el.trigger('click');
- });
-
- QUnit.test('undelegate with selector', function(assert) {
- assert.expect(2);
- var myView = new Backbone.View({el: '#testElement'});
- myView.delegate('click', function() { assert.ok(true); });
- myView.delegate('click', 'h1', function() { assert.ok(false); });
- myView.undelegate('click', 'h1');
- myView.$('h1').trigger('click');
- myView.$el.trigger('click');
- });
-
- QUnit.test('undelegate with handler and selector', function(assert) {
- assert.expect(2);
- var myView = new Backbone.View({el: '#testElement'});
- myView.delegate('click', function() { assert.ok(true); });
- var handler = function(){ assert.ok(false); };
- myView.delegate('click', 'h1', handler);
- myView.undelegate('click', 'h1', handler);
- myView.$('h1').trigger('click');
- myView.$el.trigger('click');
- });
-
- QUnit.test('tagName can be provided as a string', function(assert) {
- assert.expect(1);
- var View = Backbone.View.extend({
- tagName: 'span'
- });
-
- assert.equal(new View().el.tagName, 'SPAN');
- });
-
- QUnit.test('tagName can be provided as a function', function(assert) {
- assert.expect(1);
- var View = Backbone.View.extend({
- tagName: function() {
- return 'p';
- }
- });
-
- assert.ok(new View().$el.is('p'));
- });
-
- QUnit.test('_ensureElement with DOM node el', function(assert) {
- assert.expect(1);
- var View = Backbone.View.extend({
- el: document.body
- });
-
- assert.equal(new View().el, document.body);
- });
-
- QUnit.test('_ensureElement with string el', function(assert) {
- assert.expect(3);
- var View = Backbone.View.extend({
- el: 'body'
- });
- assert.strictEqual(new View().el, document.body);
-
- View = Backbone.View.extend({
- el: '#testElement > h1'
- });
- assert.strictEqual(new View().el, $('#testElement > h1').get(0));
-
- View = Backbone.View.extend({
- el: '#nonexistent'
- });
- assert.ok(!new View().el);
- });
-
- QUnit.test('with className and id functions', function(assert) {
- assert.expect(2);
- var View = Backbone.View.extend({
- className: function() {
- return 'className';
- },
- id: function() {
- return 'id';
- }
- });
-
- assert.strictEqual(new View().el.className, 'className');
- assert.strictEqual(new View().el.id, 'id');
- });
-
- QUnit.test('with attributes', function(assert) {
- assert.expect(2);
- var View = Backbone.View.extend({
- attributes: {
- 'id': 'id',
- 'class': 'class'
- }
- });
-
- assert.strictEqual(new View().el.className, 'class');
- assert.strictEqual(new View().el.id, 'id');
- });
-
- QUnit.test('with attributes as a function', function(assert) {
- assert.expect(1);
- var View = Backbone.View.extend({
- attributes: function() {
- return {'class': 'dynamic'};
- }
- });
-
- assert.strictEqual(new View().el.className, 'dynamic');
- });
-
- QUnit.test('should default to className/id properties', function(assert) {
- assert.expect(4);
- var View = Backbone.View.extend({
- className: 'backboneClass',
- id: 'backboneId',
- attributes: {
- 'class': 'attributeClass',
- 'id': 'attributeId'
- }
- });
-
- var myView = new View;
- assert.strictEqual(myView.el.className, 'backboneClass');
- assert.strictEqual(myView.el.id, 'backboneId');
- assert.strictEqual(myView.$el.attr('class'), 'backboneClass');
- assert.strictEqual(myView.$el.attr('id'), 'backboneId');
- });
-
- QUnit.test('multiple views per element', function(assert) {
- assert.expect(3);
- var count = 0;
- var $el = $('<p></p>');
-
- var View = Backbone.View.extend({
- el: $el,
- events: {
- click: function() {
- count++;
- }
- }
- });
-
- var view1 = new View;
- $el.trigger('click');
- assert.equal(1, count);
-
- var view2 = new View;
- $el.trigger('click');
- assert.equal(3, count);
-
- view1.delegateEvents();
- $el.trigger('click');
- assert.equal(5, count);
- });
-
- QUnit.test('custom events', function(assert) {
- assert.expect(2);
- var View = Backbone.View.extend({
- el: $('body'),
- events: {
- fake$event: function() { assert.ok(true); }
- }
- });
-
- var myView = new View;
- $('body').trigger('fake$event').trigger('fake$event');
-
- $('body').off('fake$event');
- $('body').trigger('fake$event');
- });
-
- QUnit.test('#1048 - setElement uses provided object.', function(assert) {
- assert.expect(2);
- var $el = $('body');
-
- var myView = new Backbone.View({el: $el});
- assert.ok(myView.$el === $el);
-
- myView.setElement($el = $($el));
- assert.ok(myView.$el === $el);
- });
-
- QUnit.test('#986 - Undelegate before changing element.', function(assert) {
- assert.expect(1);
- var button1 = $('<button></button>');
- var button2 = $('<button></button>');
-
- var View = Backbone.View.extend({
- events: {
- click: function(e) {
- assert.ok(myView.el === e.target);
- }
- }
- });
-
- var myView = new View({el: button1});
- myView.setElement(button2);
-
- button1.trigger('click');
- button2.trigger('click');
- });
-
- QUnit.test('#1172 - Clone attributes object', function(assert) {
- assert.expect(2);
- var View = Backbone.View.extend({
- attributes: {foo: 'bar'}
- });
-
- var view1 = new View({id: 'foo'});
- assert.strictEqual(view1.el.id, 'foo');
-
- var view2 = new View();
- assert.ok(!view2.el.id);
- });
-
- QUnit.test('views stopListening', function(assert) {
- assert.expect(0);
- var View = Backbone.View.extend({
- initialize: function() {
- this.listenTo(this.model, 'all x', function(){ assert.ok(false); });
- this.listenTo(this.collection, 'all x', function(){ assert.ok(false); });
- }
- });
-
- var myView = new View({
- model: new Backbone.Model,
- collection: new Backbone.Collection
- });
-
- myView.stopListening();
- myView.model.trigger('x');
- myView.collection.trigger('x');
- });
-
- QUnit.test('Provide function for el.', function(assert) {
- assert.expect(2);
- var View = Backbone.View.extend({
- el: function() {
- return '<p><a></a></p>';
- }
- });
-
- var myView = new View;
- assert.ok(myView.$el.is('p'));
- assert.ok(myView.$el.has('a'));
- });
-
- QUnit.test('events passed in options', function(assert) {
- assert.expect(1);
- var counter = 0;
-
- var View = Backbone.View.extend({
- el: '#testElement',
- increment: function() {
- counter++;
- }
- });
-
- var myView = new View({
- events: {
- 'click h1': 'increment'
- }
- });
-
- myView.$('h1').trigger('click').trigger('click');
- assert.equal(counter, 2);
- });
-
- QUnit.test('remove', function(assert) {
- assert.expect(2);
- var myView = new Backbone.View;
- document.body.appendChild(view.el);
-
- myView.delegate('click', function() { assert.ok(false); });
- myView.listenTo(myView, 'all x', function() { assert.ok(false); });
-
- assert.equal(myView.remove(), myView, '#remove returns the view instance');
- myView.$el.trigger('click');
- myView.trigger('x');
-
- // In IE8 and below, parentNode still exists but is not document.body.
- assert.notEqual(myView.el.parentNode, document.body);
- });
-
- QUnit.test('setElement', function(assert) {
- assert.expect(3);
- var myView = new Backbone.View({
- events: {
- click: function() { assert.ok(false); }
- }
- });
- myView.events = {
- click: function() { assert.ok(true); }
- };
- var oldEl = myView.el;
- var $oldEl = myView.$el;
-
- myView.setElement(document.createElement('div'));
-
- $oldEl.click();
- myView.$el.click();
-
- assert.notEqual(oldEl, myView.el);
- assert.notEqual($oldEl, myView.$el);
- });
-
-})();
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/license.txt b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/license.txt
deleted file mode 100644
index ba43b751..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/license.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Software License Agreement (BSD License)
-
-Copyright (c) 2007, Parakey Inc.
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of Parakey Inc. nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of Parakey Inc.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
-IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/blank.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/blank.gif
deleted file mode 100644
index 6865c960..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/blank.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/buttonBg.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/buttonBg.png
deleted file mode 100644
index f367b427..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/buttonBg.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/buttonBgHover.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/buttonBgHover.png
deleted file mode 100644
index cd37a0d5..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/buttonBgHover.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/debugger.css b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/debugger.css
deleted file mode 100644
index ba55c7ea..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/debugger.css
+++ /dev/null
@@ -1,331 +0,0 @@
-/* See license.txt for terms of usage */
-
-.panelNode-script {
- overflow: hidden;
- font-family: monospace;
-}
-
-/************************************************************************************************/
-
-.scriptTooltip {
- position: fixed;
- z-index: 2147483647;
- padding: 2px 3px;
- border: 1px solid #CBE087;
- background: LightYellow;
- font-family: monospace;
- color: #000000;
-}
-
-/************************************************************************************************/
-
-.sourceBox {
- /* TODO: xxxpedro problem with sourceBox and scrolling elements */
- /*overflow: scroll; /* see issue 1479 */
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
-}
-
-.sourceRow {
- white-space: nowrap;
- -moz-user-select: text;
-}
-
-.sourceRow.hovered {
- background-color: #EEEEEE;
-}
-
-/************************************************************************************************/
-
-.sourceLine {
- -moz-user-select: none;
- margin-right: 10px;
- border-right: 1px solid #CCCCCC;
- padding: 0px 4px 0 20px;
- background: #EEEEEE no-repeat 2px 0px;
- color: #888888;
- white-space: pre;
- font-family: monospace; /* see issue 2953 */
-}
-
-.noteInToolTip { /* below sourceLine, so it overrides it */
- background-color: #FFD472;
-}
-
-.useA11y .sourceBox .sourceViewport:focus .sourceLine {
- background-color: #FFFFC0;
- color: navy;
- border-right: 1px solid black;
-}
-
-.useA11y .sourceBox .sourceViewport:focus {
- outline: none;
-}
-
-.a11y1emSize {
- width: 1em;
- height: 1em;
- position: absolute;
-}
-
-.useA11y .panelStatusLabel:focus {
- outline-offset: -2px !important;
- }
-
-.sourceBox > .sourceRow > .sourceLine {
- cursor: pointer;
-}
-
-.sourceLine:hover {
- text-decoration: none;
-}
-
-.sourceRowText {
- white-space: pre;
-}
-
-.sourceRow[exe_line="true"] {
- outline: 1px solid #D9D9B6;
- margin-right: 1px;
- background-color: lightgoldenrodyellow;
-}
-
-.sourceRow[executable="true"] > .sourceLine {
- content: "-";
- color: #4AA02C; /* Spring Green */
- font-weight: bold;
-}
-
-.sourceRow[exe_line="true"] > .sourceLine {
- background-image: url(chrome://firebug/skin/exe.png);
- color: #000000;
-}
-
-.sourceRow[breakpoint="true"] > .sourceLine {
- background-image: url(chrome://firebug/skin/breakpoint.png);
-}
-
-.sourceRow[breakpoint="true"][condition="true"] > .sourceLine {
- background-image: url(chrome://firebug/skin/breakpointCondition.png);
-}
-
-.sourceRow[breakpoint="true"][disabledBreakpoint="true"] > .sourceLine {
- background-image: url(chrome://firebug/skin/breakpointDisabled.png);
-}
-
-.sourceRow[breakpoint="true"][exe_line="true"] > .sourceLine {
- background-image: url(chrome://firebug/skin/breakpointExe.png);
-}
-
-.sourceRow[breakpoint="true"][exe_line="true"][disabledBreakpoint="true"] > .sourceLine {
- background-image: url(chrome://firebug/skin/breakpointDisabledExe.png);
-}
-
-.sourceLine.editing {
- background-image: url(chrome://firebug/skin/breakpoint.png);
-}
-
-/************************************************************************************************/
-
-.conditionEditor {
- z-index: 2147483647;
- position: absolute;
- margin-top: 0;
- left: 2px;
- width: 90%;
-}
-
-.conditionEditorInner {
- position: relative;
- top: -26px;
- height: 0;
-}
-
-.conditionCaption {
- margin-bottom: 2px;
- font-family: Lucida Grande, sans-serif;
- font-weight: bold;
- font-size: 11px;
- color: #226679;
-}
-
-.conditionInput {
- width: 100%;
- border: 1px solid #0096C0;
- font-family: monospace;
- font-size: inherit;
-}
-
-.conditionEditorInner1 {
- padding-left: 37px;
- background: url(condBorders.png) repeat-y;
-}
-
-.conditionEditorInner2 {
- padding-right: 25px;
- background: url(condBorders.png) repeat-y 100% 0;
-}
-
-.conditionEditorTop1 {
- background: url(condCorners.png) no-repeat 100% 0;
- margin-left: 37px;
- height: 35px;
-}
-
-.conditionEditorTop2 {
- position: relative;
- left: -37px;
- width: 37px;
- height: 35px;
- background: url(condCorners.png) no-repeat;
-}
-
-.conditionEditorBottom1 {
- background: url(condCorners.png) no-repeat 100% 100%;
- margin-left: 37px;
- height: 33px;
-}
-
-.conditionEditorBottom2 {
- position: relative; left: -37px;
- width: 37px;
- height: 33px;
- background: url(condCorners.png) no-repeat 0 100%;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.upsideDown {
- margin-top: 2px;
-}
-
-.upsideDown .conditionEditorInner {
- top: -8px;
-}
-
-.upsideDown .conditionEditorInner1 {
- padding-left: 33px;
- background: url(condBordersUps.png) repeat-y;
-}
-
-.upsideDown .conditionEditorInner2 {
- padding-right: 25px;
- background: url(condBordersUps.png) repeat-y 100% 0;
-}
-
-.upsideDown .conditionEditorTop1 {
- background: url(condCornersUps.png) no-repeat 100% 0;
- margin-left: 33px;
- height: 25px;
-}
-
-.upsideDown .conditionEditorTop2 {
- position: relative;
- left: -33px;
- width: 33px;
- height: 25px;
- background: url(condCornersUps.png) no-repeat;
-}
-
-.upsideDown .conditionEditorBottom1 {
- background: url(condCornersUps.png) no-repeat 100% 100%;
- margin-left: 33px;
- height: 43px;
-}
-
-.upsideDown .conditionEditorBottom2 {
- position: relative;
- left: -33px;
- width: 33px;
- height: 43px;
- background: url(condCornersUps.png) no-repeat 0 100%;
-}
-
-/************************************************************************************************/
-
-.breakpointsGroupListBox {
- overflow: hidden;
-}
-
-.breakpointBlockHead {
- position: relative;
- padding-top: 4px;
-}
-
-.breakpointBlockHead > .checkbox {
- margin-right: 4px;
-}
-
-.breakpointBlockHead > .objectLink-sourceLink {
- top: 4px;
- right: 20px;
- background-color: #FFFFFF; /* issue 3308 */
-}
-
-.breakpointBlockHead > .closeButton {
- position: absolute;
- top: 2px;
- right: 2px;
-}
-
-.breakpointCheckbox {
- margin-top: 0;
- vertical-align: top;
-}
-
-.breakpointName {
- margin-left: 4px;
- font-weight: bold;
-}
-
-.breakpointRow[aria-checked="false"] > .breakpointBlockHead > *,
-.breakpointRow[aria-checked="false"] > .breakpointCode {
- opacity: 0.5;
-}
-
-.breakpointRow[aria-checked="false"] .breakpointCheckbox,
-.breakpointRow[aria-checked="false"] .objectLink-sourceLink,
-.breakpointRow[aria-checked="false"] .closeButton,
-.breakpointRow[aria-checked="false"] .breakpointMutationType {
- opacity: 1.0 !important;
-}
-
-.breakpointCode {
- overflow: hidden;
- white-space: nowrap;
- padding-left: 24px;
- padding-bottom: 2px;
- border-bottom: 1px solid #D7D7D7;
- font-family: monospace;
- color: DarkGreen;
-}
-
-.breakpointCondition {
- white-space: nowrap;
- padding-left: 24px;
- padding-bottom: 2px;
- border-bottom: 1px solid #D7D7D7;
- font-family: monospace;
- color: Gray;
-}
-
-.breakpointBlock-breakpoints > .groupHeader {
- display: none;
-}
-
-.breakpointBlock-monitors > .breakpointCode {
- padding: 0;
-}
-
-.breakpointBlock-errorBreakpoints .breakpointCheckbox,
-.breakpointBlock-monitors .breakpointCheckbox {
- display: none;
-}
-
-.breakpointHeader {
- margin: 0 !important;
- border-top: none !important;
-}
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/detach.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/detach.png
deleted file mode 100644
index 0ddb9a17..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/detach.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/detachHover.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/detachHover.png
deleted file mode 100644
index e4192729..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/detachHover.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disable.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disable.gif
deleted file mode 100644
index dd9eb0e3..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disable.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disable.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disable.png
deleted file mode 100644
index c28bcdf2..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disable.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disableHover.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disableHover.gif
deleted file mode 100644
index 70565a83..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disableHover.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disableHover.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disableHover.png
deleted file mode 100644
index 26fe3754..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/disableHover.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/down.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/down.png
deleted file mode 100644
index acbbd30c..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/down.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/downActive.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/downActive.png
deleted file mode 100644
index f4312b2f..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/downActive.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/downHover.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/downHover.png
deleted file mode 100644
index 8144e637..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/downHover.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/errorIcon-sm.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/errorIcon-sm.png
deleted file mode 100644
index 0c377e30..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/errorIcon-sm.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/errorIcon.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/errorIcon.gif
deleted file mode 100644
index 8ee8116a..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/errorIcon.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/errorIcon.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/errorIcon.png
deleted file mode 100644
index 2d75261b..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/errorIcon.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug-1.3a2.css b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug-1.3a2.css
deleted file mode 100644
index 42f9faf5..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug-1.3a2.css
+++ /dev/null
@@ -1,817 +0,0 @@
-.fbBtnPressed {
- background: #ECEBE3;
- padding: 3px 6px 2px 7px !important;
- margin: 1px 0 0 1px;
- _margin: 1px -1px 0 1px;
- border: 1px solid #ACA899 !important;
- border-color: #ACA899 #ECEBE3 #ECEBE3 #ACA899 !important;
-}
-
-.fbToolbarButtons {
- display: none;
-}
-
-#fbStatusBarBox {
- display: none;
-}
-
-/************************************************************************************************
- Error Popup
-*************************************************************************************************/
-#fbErrorPopup {
- position: absolute;
- right: 0;
- bottom: 0;
- height: 19px;
- width: 75px;
- background: url(sprite.png) #f1f2ee 0 0;
- z-index: 999;
-}
-
-#fbErrorPopupContent {
- position: absolute;
- right: 0;
- top: 1px;
- height: 18px;
- width: 75px;
- _width: 74px;
- border-left: 1px solid #aca899;
-}
-
-#fbErrorIndicator {
- position: absolute;
- top: 2px;
- right: 5px;
-}
-
-
-
-
-
-
-
-
-
-
-.fbBtnInspectActive {
- background: #aaa;
- color: #fff !important;
-}
-
-/************************************************************************************************
- General
-*************************************************************************************************/
-html, body {
- margin: 0;
- padding: 0;
- overflow: hidden;
-}
-
-body {
- font-family: Lucida Grande, Tahoma, sans-serif;
- font-size: 11px;
- background: #fff;
-}
-
-.clear {
- clear: both;
-}
-
-/************************************************************************************************
- Mini Chrome
-*************************************************************************************************/
-#fbMiniChrome {
- display: none;
- right: 0;
- height: 27px;
- background: url(sprite.png) #f1f2ee 0 0;
- margin-left: 1px;
-}
-
-#fbMiniContent {
- display: block;
- position: relative;
- left: -1px;
- right: 0;
- top: 1px;
- height: 25px;
- border-left: 1px solid #aca899;
-}
-
-#fbToolbarSearch {
- float: right;
- border: 1px solid #ccc;
- margin: 0 5px 0 0;
- background: #fff url(search.png) no-repeat 4px 2px;
- padding-left: 20px;
- font-size: 11px;
-}
-
-#fbToolbarErrors {
- float: right;
- margin: 1px 4px 0 0;
- font-size: 11px;
-}
-
-#fbLeftToolbarErrors {
- float: left;
- margin: 7px 0px 0 5px;
- font-size: 11px;
-}
-
-.fbErrors {
- padding-left: 20px;
- height: 14px;
- background: url(errorIcon.png) no-repeat;
- color: #f00;
- font-weight: bold;
-}
-
-#fbMiniErrors {
- display: inline;
- display: none;
- float: right;
- margin: 5px 2px 0 5px;
-}
-
-#fbMiniIcon {
- float: right;
- margin: 3px 4px 0;
- height: 20px;
- width: 20px;
- float: right;
- background: url(sprite.png) 0 -135px;
- cursor: pointer;
-}
-
-
-/************************************************************************************************
- Master Layout
-*************************************************************************************************/
-#fbChrome {
- position: fixed;
- overflow: hidden;
- height: 100%;
- width: 100%;
- border-collapse: collapse;
- background: #fff;
-}
-
-#fbTop {
- height: 49px;
-}
-
-#fbToolbar {
- position: absolute;
- z-index: 5;
- width: 100%;
- top: 0;
- background: url(sprite.png) #f1f2ee 0 0;
- height: 27px;
- font-size: 11px;
- overflow: hidden;
-}
-
-#fbPanelBarBox {
- top: 27px;
- position: absolute;
- z-index: 8;
- width: 100%;
- background: url(sprite.png) #dbd9c9 0 -27px;
- height: 22px;
-}
-
-#fbContent {
- height: 100%;
- vertical-align: top;
-}
-
-#fbBottom {
- height: 18px;
- background: #fff;
-}
-
-/************************************************************************************************
- Sub-Layout
-*************************************************************************************************/
-
-/* fbToolbar
-*************************************************************************************************/
-#fbToolbarIcon {
- float: left;
- padding: 4px 5px 0;
-}
-
-#fbToolbarIcon a {
- display: block;
- height: 20px;
- width: 20px;
- background: url(sprite.png) 0 -135px;
- text-decoration: none;
- cursor: default;
-}
-
-#fbToolbarButtons {
- float: left;
- padding: 4px 2px 0 5px;
-}
-
-#fbToolbarButtons a {
- text-decoration: none;
- display: block;
- float: left;
- color: #000;
- padding: 4px 8px 4px;
- cursor: default;
-}
-
-#fbToolbarButtons a:hover {
- color: #333;
- padding: 3px 7px 3px;
- border: 1px solid #fff;
- border-bottom: 1px solid #bbb;
- border-right: 1px solid #bbb;
-}
-
-#fbStatusBarBox {
- position: relative;
- top: 5px;
- line-height: 19px;
- cursor: default;
-}
-
-.fbToolbarSeparator{
- overflow: hidden;
- border: 1px solid;
- border-color: transparent #fff transparent #777;
- _border-color: #eee #fff #eee #777;
- height: 7px;
- margin: 10px 6px 0 0;
- float: left;
-}
-
-.fbStatusBar span {
- color: #808080;
- padding: 0 4px 0 0;
-}
-
-.fbStatusBar span a {
- text-decoration: none;
- color: black;
-}
-
-.fbStatusBar span a:hover {
- color: blue;
- cursor: pointer;
-}
-
-
-#fbWindowButtons {
- position: absolute;
- white-space: nowrap;
- right: 0;
- top: 0;
- height: 17px;
- _width: 50px;
- padding: 5px 0 5px 5px;
- z-index: 6;
- background: url(sprite.png) #f1f2ee 0 0;
-}
-
-/* fbPanelBarBox
-*************************************************************************************************/
-
-#fbPanelBar1 {
- width: 255px; /* fixed width to avoid tabs breaking line */
- z-index: 8;
- left: 0;
- white-space: nowrap;
- background: url(sprite.png) #dbd9c9 0 -27px;
- position: absolute;
- left: 4px;
-}
-
-#fbPanelBar2Box {
- background: url(sprite.png) #dbd9c9 0 -27px;
- position: absolute;
- height: 22px;
- width: 300px; /* fixed width to avoid tabs breaking line */
- z-index: 9;
- right: 0;
-}
-
-#fbPanelBar2 {
- position: absolute;
- width: 290px; /* fixed width to avoid tabs breaking line */
- height: 22px;
- padding-left: 10px;
-}
-
-/* body
-*************************************************************************************************/
-.fbPanel {
- display: none;
-}
-
-#fbPanelBox1, #fbPanelBox2 {
- max-height: inherit;
- height: 100%;
- font-size: 11px;
-}
-
-#fbPanelBox2 {
- background: #fff;
-}
-
-#fbPanelBox2 {
- width: 300px;
- background: #fff;
-}
-
-#fbPanel2 {
- padding-left: 6px;
- background: #fff;
-}
-
-.hide {
- overflow: hidden !important;
- position: fixed !important;
- display: none !important;
- visibility: hidden !important;
-}
-
-/* fbBottom
-*************************************************************************************************/
-
-#fbCommand {
- height: 18px;
-}
-
-#fbCommandBox {
- position: absolute;
- width: 100%;
- height: 18px;
- bottom: 0;
- overflow: hidden;
- z-index: 9;
- background: #fff;
- border: 0;
- border-top: 1px solid #ccc;
-}
-
-#fbCommandIcon {
- position: absolute;
- color: #00f;
- top: 2px;
- left: 7px;
- display: inline;
- font: 11px Monaco, monospace;
- z-index: 10;
-}
-
-#fbCommandLine {
- position: absolute;
- width: 100%;
- top: 0;
- left: 0;
- border: 0;
- margin: 0;
- padding: 2px 0 2px 32px;
- font: 11px Monaco, monospace;
- z-index: 9;
-}
-
-div.fbFitHeight {
- overflow: auto;
- _position: absolute;
-}
-
-
-/************************************************************************************************
- Layout Controls
-*************************************************************************************************/
-
-/* fbToolbar buttons
-*************************************************************************************************/
-#fbWindowButtons a {
- font-size: 1px;
- width: 16px;
- height: 16px;
- display: block;
- float: right;
- margin-right: 4px;
- text-decoration: none;
- cursor: default;
-}
-
-#fbWindow_btClose {
- background: url(sprite.png) 0 -119px;
-}
-
-#fbWindow_btClose:hover {
- background: url(sprite.png) -16px -119px;
-}
-
-#fbWindow_btDetach {
- background: url(sprite.png) -32px -119px;
-}
-
-#fbWindow_btDetach:hover {
- background: url(sprite.png) -48px -119px;
-}
-
-/* fbPanelBarBox tabs
-*************************************************************************************************/
-.fbTab {
- text-decoration: none;
- display: none;
- float: left;
- width: auto;
- float: left;
- cursor: default;
- font-family: Lucida Grande, Tahoma, sans-serif;
- font-size: 11px;
- font-weight: bold;
- height: 22px;
- color: #565656;
-}
-
-.fbPanelBar span {
- display: block;
- float: left;
-}
-
-.fbPanelBar .fbTabL,.fbPanelBar .fbTabR {
- height: 22px;
- width: 8px;
-}
-
-.fbPanelBar .fbTabText {
- padding: 4px 1px 0;
-}
-
-a.fbTab:hover {
- background: url(sprite.png) 0 -73px;
-}
-
-a.fbTab:hover .fbTabL {
- background: url(sprite.png) -16px -96px;
-}
-
-a.fbTab:hover .fbTabR {
- background: url(sprite.png) -24px -96px;
-}
-
-.fbSelectedTab {
- background: url(sprite.png) #f1f2ee 0 -50px !important;
- color: #000;
-}
-
-.fbSelectedTab .fbTabL {
- background: url(sprite.png) 0 -96px !important;
-}
-
-.fbSelectedTab .fbTabR {
- background: url(sprite.png) -8px -96px !important;
-}
-
-/* splitters
-*************************************************************************************************/
-#fbHSplitter {
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- height: 5px;
- overflow: hidden;
- cursor: n-resize !important;
- background: url(pixel_transparent.gif);
- z-index: 9;
-}
-
-#fbHSplitter.fbOnMovingHSplitter {
- height: 100%;
- z-index: 100;
-}
-
-.fbVSplitter {
- background: #ece9d8;
- color: #000;
- border: 1px solid #716f64;
- border-width: 0 1px;
- border-left-color: #aca899;
- width: 4px;
- cursor: e-resize;
- overflow: hidden;
- right: 294px;
- text-decoration: none;
- z-index: 9;
- position: absolute;
- height: 100%;
- top: 27px;
- _width: 6px;
-}
-
-/************************************************************************************************/
-div.lineNo {
- font: 11px Monaco, monospace;
- float: left;
- display: inline;
- position: relative;
- margin: 0;
- padding: 0 5px 0 20px;
- background: #eee;
- color: #888;
- border-right: 1px solid #ccc;
- text-align: right;
-}
-
-pre.nodeCode {
- font: 11px Monaco, monospace;
- margin: 0;
- padding-left: 10px;
- overflow: hidden;
- /*
- _width: 100%;
- /**/
-}
-
-/************************************************************************************************/
-.nodeControl {
- margin-top: 3px;
- margin-left: -14px;
- float: left;
- width: 9px;
- height: 9px;
- overflow: hidden;
- cursor: default;
- background: url(tree_open.gif);
- _float: none;
- _display: inline;
- _position: absolute;
-}
-
-div.nodeMaximized {
- background: url(tree_close.gif);
-}
-
-div.objectBox-element {
- padding: 1px 3px;
-}
-.objectBox-selector{
- cursor: default;
-}
-
-.selectedElement{
- background: highlight;
- /* background: url(roundCorner.svg); Opera */
- color: #fff !important;
-}
-.selectedElement span{
- color: #fff !important;
-}
-
-/* Webkit CSS Hack - bug in "highlight" named color */
-@media screen and (-webkit-min-device-pixel-ratio:0) {
- .selectedElement{
- background: #316AC5;
- color: #fff !important;
- }
-}
-
-/************************************************************************************************/
-/************************************************************************************************/
-.logRow * {
- font-size: 11px;
-}
-
-.logRow {
- position: relative;
- border-bottom: 1px solid #D7D7D7;
- padding: 2px 4px 1px 6px;
- background-color: #FFFFFF;
-}
-
-.logRow-command {
- font-family: Monaco, monospace;
- color: blue;
-}
-
-.objectBox-string,
-.objectBox-text,
-.objectBox-number,
-.objectBox-function,
-.objectLink-element,
-.objectLink-textNode,
-.objectLink-function,
-.objectBox-stackTrace,
-.objectLink-profile {
- font-family: Monaco, monospace;
-}
-
-.objectBox-null {
- padding: 0 2px;
- border: 1px solid #666666;
- background-color: #888888;
- color: #FFFFFF;
-}
-
-.objectBox-string {
- color: red;
- white-space: pre;
-}
-
-.objectBox-number {
- color: #000088;
-}
-
-.objectBox-function {
- color: DarkGreen;
-}
-
-.objectBox-object {
- color: DarkGreen;
- font-weight: bold;
- font-family: Lucida Grande, sans-serif;
-}
-
-.objectBox-array {
- color: #000;
-}
-
-/************************************************************************************************/
-.logRow-info,.logRow-error,.logRow-warning {
- background: #fff no-repeat 2px 2px;
- padding-left: 20px;
- padding-bottom: 3px;
-}
-
-.logRow-info {
- background-image: url(infoIcon.png);
-}
-
-.logRow-warning {
- background-color: cyan;
- background-image: url(warningIcon.png);
-}
-
-.logRow-error {
- background-color: LightYellow;
- background-image: url(errorIcon.png);
- color: #f00;
-}
-
-.errorMessage {
- vertical-align: top;
- color: #f00;
-}
-
-.objectBox-sourceLink {
- position: absolute;
- right: 4px;
- top: 2px;
- padding-left: 8px;
- font-family: Lucida Grande, sans-serif;
- font-weight: bold;
- color: #0000FF;
-}
-
-/************************************************************************************************/
-.logRow-group {
- background: #EEEEEE;
- border-bottom: none;
-}
-
-.logGroup {
- background: #EEEEEE;
-}
-
-.logGroupBox {
- margin-left: 24px;
- border-top: 1px solid #D7D7D7;
- border-left: 1px solid #D7D7D7;
-}
-
-/************************************************************************************************/
-.selectorTag,.selectorId,.selectorClass {
- font-family: Monaco, monospace;
- font-weight: normal;
-}
-
-.selectorTag {
- color: #0000FF;
-}
-
-.selectorId {
- color: DarkBlue;
-}
-
-.selectorClass {
- color: red;
-}
-
-/************************************************************************************************/
-.objectBox-element {
- font-family: Monaco, monospace;
- color: #000088;
-}
-
-.nodeChildren {
- padding-left: 26px;
-}
-
-.nodeTag {
- color: blue;
- cursor: pointer;
-}
-
-.nodeValue {
- color: #FF0000;
- font-weight: normal;
-}
-
-.nodeText,.nodeComment {
- margin: 0 2px;
- vertical-align: top;
-}
-
-.nodeText {
- color: #333333;
- font-family: Monaco, monospace;
-}
-
-.nodeComment {
- color: DarkGreen;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.nodeHidden, .nodeHidden * {
- color: #888888;
-}
-
-.nodeHidden .nodeTag {
- color: #5F82D9;
-}
-
-.nodeHidden .nodeValue {
- color: #D86060;
-}
-
-.selectedElement .nodeHidden, .selectedElement .nodeHidden * {
- color: SkyBlue !important;
-}
-
-
-/************************************************************************************************/
-.log-object {
- /*
- _position: relative;
- _height: 100%;
- /**/
-}
-
-.property {
- position: relative;
- clear: both;
- height: 15px;
-}
-
-.propertyNameCell {
- vertical-align: top;
- float: left;
- width: 28%;
- position: absolute;
- left: 0;
- z-index: 0;
-}
-
-.propertyValueCell {
- float: right;
- width: 68%;
- background: #fff;
- position: absolute;
- padding-left: 5px;
- display: table-cell;
- right: 0;
- z-index: 1;
- /*
- _position: relative;
- /**/
-}
-
-.propertyName {
- font-weight: bold;
-}
-
-.FirebugPopup {
- height: 100% !important;
-}
-
-.FirebugPopup #fbWindowButtons {
- display: none !important;
-}
-
-.FirebugPopup #fbHSplitter {
- display: none !important;
-}
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.IE6.css b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.IE6.css
deleted file mode 100644
index 13a41d28..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.IE6.css
+++ /dev/null
@@ -1,20 +0,0 @@
-/************************************************************************************************/
-#fbToolbarSearch {
- background-image: url(search.gif) !important;
-}
-/************************************************************************************************/
-.fbErrors {
- background-image: url(errorIcon.gif) !important;
-}
-/************************************************************************************************/
-.logRow-info {
- background-image: url(infoIcon.gif) !important;
-}
-
-.logRow-warning {
- background-image: url(warningIcon.gif) !important;
-}
-
-.logRow-error {
- background-image: url(errorIcon.gif) !important;
-}
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.css b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.css
deleted file mode 100644
index a1465ec5..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.css
+++ /dev/null
@@ -1,3147 +0,0 @@
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/* Loose */
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*
-.netInfoResponseHeadersTitle, netInfoResponseHeadersBody {
- display: none;
-}
-/**/
-
-.obscured {
- left: -999999px !important;
-}
-
-/* IE6 need a separated rule, otherwise it will not recognize it */
-.collapsed {
- display: none;
-}
-
-[collapsed="true"] {
- display: none;
-}
-
-#fbCSS {
- padding: 0 !important;
-}
-
-.cssPropDisable {
- float: left;
- display: block;
- width: 2em;
- cursor: default;
-}
-
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/* panelBase */
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-
-/************************************************************************************************/
-
-.infoTip {
- z-index: 2147483647;
- position: fixed;
- padding: 2px 3px;
- border: 1px solid #CBE087;
- background: LightYellow;
- font-family: Monaco, monospace;
- color: #000000;
- display: none;
- white-space: nowrap;
- pointer-events: none;
-}
-
-.infoTip[active="true"] {
- display: block;
-}
-
-.infoTipLoading {
- width: 16px;
- height: 16px;
- background: url(chrome://firebug/skin/loading_16.gif) no-repeat;
-}
-
-.infoTipImageBox {
- font-size: 11px;
- min-width: 100px;
- text-align: center;
-}
-
-.infoTipCaption {
- font-size: 11px;
- font: Monaco, monospace;
-}
-
-.infoTipLoading > .infoTipImage,
-.infoTipLoading > .infoTipCaption {
- display: none;
-}
-
-/************************************************************************************************/
-
-h1.groupHeader {
- padding: 2px 4px;
- margin: 0 0 4px 0;
- border-top: 1px solid #CCCCCC;
- border-bottom: 1px solid #CCCCCC;
- background: #eee url(group.gif) repeat-x;
- font-size: 11px;
- font-weight: bold;
- _position: relative;
-}
-
-/************************************************************************************************/
-
-.inlineEditor,
-.fixedWidthEditor {
- z-index: 2147483647;
- position: absolute;
- display: none;
-}
-
-.inlineEditor {
- margin-left: -6px;
- margin-top: -3px;
- /*
- _margin-left: -7px;
- _margin-top: -5px;
- /**/
-}
-
-.textEditorInner,
-.fixedWidthEditor {
- margin: 0 0 0 0 !important;
- padding: 0;
- border: none !important;
- font: inherit;
- text-decoration: inherit;
- background-color: #FFFFFF;
-}
-
-.fixedWidthEditor {
- border-top: 1px solid #888888 !important;
- border-bottom: 1px solid #888888 !important;
-}
-
-.textEditorInner {
- position: relative;
- top: -7px;
- left: -5px;
-
- outline: none;
- resize: none;
-
- /*
- _border: 1px solid #999 !important;
- _padding: 1px !important;
- _filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color="#55404040");
- /**/
-}
-
-.textEditorInner1 {
- padding-left: 11px;
- background: url(textEditorBorders.png) repeat-y;
- _background: url(textEditorBorders.gif) repeat-y;
- _overflow: hidden;
-}
-
-.textEditorInner2 {
- position: relative;
- padding-right: 2px;
- background: url(textEditorBorders.png) repeat-y 100% 0;
- _background: url(textEditorBorders.gif) repeat-y 100% 0;
- _position: fixed;
-}
-
-.textEditorTop1 {
- background: url(textEditorCorners.png) no-repeat 100% 0;
- margin-left: 11px;
- height: 10px;
- _background: url(textEditorCorners.gif) no-repeat 100% 0;
- _overflow: hidden;
-}
-
-.textEditorTop2 {
- position: relative;
- left: -11px;
- width: 11px;
- height: 10px;
- background: url(textEditorCorners.png) no-repeat;
- _background: url(textEditorCorners.gif) no-repeat;
-}
-
-.textEditorBottom1 {
- position: relative;
- background: url(textEditorCorners.png) no-repeat 100% 100%;
- margin-left: 11px;
- height: 12px;
- _background: url(textEditorCorners.gif) no-repeat 100% 100%;
-}
-
-.textEditorBottom2 {
- position: relative;
- left: -11px;
- width: 11px;
- height: 12px;
- background: url(textEditorCorners.png) no-repeat 0 100%;
- _background: url(textEditorCorners.gif) no-repeat 0 100%;
-}
-
-
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/* CSS */
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-
-/* See license.txt for terms of usage */
-
-.panelNode-css {
- overflow-x: hidden;
-}
-
-.cssSheet > .insertBefore {
- height: 1.5em;
-}
-
-.cssRule {
- position: relative;
- margin: 0;
- padding: 1em 0 0 6px;
- font-family: Monaco, monospace;
- color: #000000;
-}
-
-.cssRule:first-child {
- padding-top: 6px;
-}
-
-.cssElementRuleContainer {
- position: relative;
-}
-
-.cssHead {
- padding-right: 150px;
-}
-
-.cssProp {
- /*padding-left: 2em;*/
-}
-
-.cssPropName {
- color: DarkGreen;
-}
-
-.cssPropValue {
- margin-left: 8px;
- color: DarkBlue;
-}
-
-.cssOverridden span {
- text-decoration: line-through;
-}
-
-.cssInheritedRule {
-}
-
-.cssInheritLabel {
- margin-right: 0.5em;
- font-weight: bold;
-}
-
-.cssRule .objectLink-sourceLink {
- top: 0;
-}
-
-.cssProp.editGroup:hover {
- background: url(disable.png) no-repeat 2px 1px;
- _background: url(disable.gif) no-repeat 2px 1px;
-}
-
-.cssProp.editGroup.editing {
- background: none;
-}
-
-.cssProp.disabledStyle {
- background: url(disableHover.png) no-repeat 2px 1px;
- _background: url(disableHover.gif) no-repeat 2px 1px;
- opacity: 1;
- color: #CCCCCC;
-}
-
-.disabledStyle .cssPropName,
-.disabledStyle .cssPropValue {
- color: #CCCCCC;
-}
-
-.cssPropValue.editing + .cssSemi,
-.inlineExpander + .cssSemi {
- display: none;
-}
-
-.cssPropValue.editing {
- white-space: nowrap;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.stylePropName {
- font-weight: bold;
- padding: 0 4px 4px 4px;
- width: 50%;
-}
-
-.stylePropValue {
- width: 50%;
-}
-/*
-.useA11y .a11yCSSView .focusRow:focus {
- outline: none;
- background-color: transparent
- }
-
- .useA11y .a11yCSSView .focusRow:focus .cssSelector,
- .useA11y .a11yCSSView .focusRow:focus .cssPropName,
- .useA11y .a11yCSSView .focusRow:focus .cssPropValue,
- .useA11y .a11yCSSView .computedStyleRow:focus,
- .useA11y .a11yCSSView .groupHeader:focus {
- outline: 2px solid #FF9933;
- outline-offset: -2px;
- background-color: #FFFFD6;
- }
-
- .useA11y .a11yCSSView .groupHeader:focus {
- outline-offset: -2px;
- }
-/**/
-
-
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/* Net */
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-
-/* See license.txt for terms of usage */
-
-.panelNode-net {
- overflow-x: hidden;
-}
-
-.netTable {
- width: 100%;
-}
-
-/************************************************************************************************/
-
-.hideCategory-undefined .category-undefined,
-.hideCategory-html .category-html,
-.hideCategory-css .category-css,
-.hideCategory-js .category-js,
-.hideCategory-image .category-image,
-.hideCategory-xhr .category-xhr,
-.hideCategory-flash .category-flash,
-.hideCategory-txt .category-txt,
-.hideCategory-bin .category-bin {
- display: none;
-}
-
-/************************************************************************************************/
-
-.netHeadRow {
- background: url(chrome://firebug/skin/group.gif) repeat-x #FFFFFF;
-}
-
-.netHeadCol {
- border-bottom: 1px solid #CCCCCC;
- padding: 2px 4px 2px 18px;
- font-weight: bold;
-}
-
-.netHeadLabel {
- white-space: nowrap;
- overflow: hidden;
-}
-
-/************************************************************************************************/
-/* Header for Net panel table */
-
-.netHeaderRow {
- height: 16px;
-}
-
-.netHeaderCell {
- cursor: pointer;
- -moz-user-select: none;
- border-bottom: 1px solid #9C9C9C;
- padding: 0 !important;
- font-weight: bold;
- background: #BBBBBB url(chrome://firebug/skin/tableHeader.gif) repeat-x;
- white-space: nowrap;
-}
-
-.netHeaderRow > .netHeaderCell:first-child > .netHeaderCellBox {
- padding: 2px 14px 2px 18px;
-}
-
-.netHeaderCellBox {
- padding: 2px 14px 2px 10px;
- border-left: 1px solid #D9D9D9;
- border-right: 1px solid #9C9C9C;
-}
-
-.netHeaderCell:hover:active {
- background: #959595 url(chrome://firebug/skin/tableHeaderActive.gif) repeat-x;
-}
-
-.netHeaderSorted {
- background: #7D93B2 url(chrome://firebug/skin/tableHeaderSorted.gif) repeat-x;
-}
-
-.netHeaderSorted > .netHeaderCellBox {
- border-right-color: #6B7C93;
- background: url(chrome://firebug/skin/arrowDown.png) no-repeat right;
-}
-
-.netHeaderSorted.sortedAscending > .netHeaderCellBox {
- background-image: url(chrome://firebug/skin/arrowUp.png);
-}
-
-.netHeaderSorted:hover:active {
- background: #536B90 url(chrome://firebug/skin/tableHeaderSortedActive.gif) repeat-x;
-}
-
-/************************************************************************************************/
-/* Breakpoints */
-
-.panelNode-net .netRowHeader {
- display: block;
-}
-
-.netRowHeader {
- cursor: pointer;
- display: none;
- height: 15px;
- margin-right: 0 !important;
-}
-
-/* Display brekpoint disc */
-.netRow .netRowHeader {
- background-position: 5px 1px;
-}
-
-.netRow[breakpoint="true"] .netRowHeader {
- background-image: url(chrome://firebug/skin/breakpoint.png);
-}
-
-.netRow[breakpoint="true"][disabledBreakpoint="true"] .netRowHeader {
- background-image: url(chrome://firebug/skin/breakpointDisabled.png);
-}
-
-.netRow.category-xhr:hover .netRowHeader {
- background-color: #F6F6F6;
-}
-
-#netBreakpointBar {
- max-width: 38px;
-}
-
-#netHrefCol > .netHeaderCellBox {
- border-left: 0px;
-}
-
-.netRow .netRowHeader {
- width: 3px;
-}
-
-.netInfoRow .netRowHeader {
- display: table-cell;
-}
-
-/************************************************************************************************/
-/* Column visibility */
-
-.netTable[hiddenCols~=netHrefCol] TD[id="netHrefCol"],
-.netTable[hiddenCols~=netHrefCol] TD.netHrefCol,
-.netTable[hiddenCols~=netStatusCol] TD[id="netStatusCol"],
-.netTable[hiddenCols~=netStatusCol] TD.netStatusCol,
-.netTable[hiddenCols~=netDomainCol] TD[id="netDomainCol"],
-.netTable[hiddenCols~=netDomainCol] TD.netDomainCol,
-.netTable[hiddenCols~=netSizeCol] TD[id="netSizeCol"],
-.netTable[hiddenCols~=netSizeCol] TD.netSizeCol,
-.netTable[hiddenCols~=netTimeCol] TD[id="netTimeCol"],
-.netTable[hiddenCols~=netTimeCol] TD.netTimeCol {
- display: none;
-}
-
-/************************************************************************************************/
-
-.netRow {
- background: LightYellow;
-}
-
-.netRow.loaded {
- background: #FFFFFF;
-}
-
-.netRow.loaded:hover {
- background: #EFEFEF;
-}
-
-.netCol {
- padding: 0;
- vertical-align: top;
- border-bottom: 1px solid #EFEFEF;
- white-space: nowrap;
- height: 17px;
-}
-
-.netLabel {
- width: 100%;
-}
-
-.netStatusCol {
- padding-left: 10px;
- color: rgb(128, 128, 128);
-}
-
-.responseError > .netStatusCol {
- color: red;
-}
-
-.netDomainCol {
- padding-left: 5px;
-}
-
-.netSizeCol {
- text-align: right;
- padding-right: 10px;
-}
-
-.netHrefLabel {
- -moz-box-sizing: padding-box;
- overflow: hidden;
- z-index: 10;
- position: absolute;
- padding-left: 18px;
- padding-top: 1px;
- max-width: 15%;
- font-weight: bold;
-}
-
-.netFullHrefLabel {
- display: none;
- -moz-user-select: none;
- padding-right: 10px;
- padding-bottom: 3px;
- max-width: 100%;
- background: #FFFFFF;
- z-index: 200;
-}
-
-.netHrefCol:hover > .netFullHrefLabel {
- display: block;
-}
-
-.netRow.loaded:hover .netCol > .netFullHrefLabel {
- background-color: #EFEFEF;
-}
-
-.useA11y .a11yShowFullLabel {
- display: block;
- background-image: none !important;
- border: 1px solid #CBE087;
- background-color: LightYellow;
- font-family: Monaco, monospace;
- color: #000000;
- font-size: 10px;
- z-index: 2147483647;
-}
-
-.netSizeLabel {
- padding-left: 6px;
-}
-
-.netStatusLabel,
-.netDomainLabel,
-.netSizeLabel,
-.netBar {
- padding: 1px 0 2px 0 !important;
-}
-
-.responseError {
- color: red;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.hasHeaders .netHrefLabel:hover {
- cursor: pointer;
- color: blue;
- text-decoration: underline;
-}
-
-/************************************************************************************************/
-
-.netLoadingIcon {
- position: absolute;
- border: 0;
- margin-left: 14px;
- width: 16px;
- height: 16px;
- background: transparent no-repeat 0 0;
- background-image: url(chrome://firebug/skin/loading_16.gif);
- display:inline-block;
-}
-
-.loaded .netLoadingIcon {
- display: none;
-}
-
-/************************************************************************************************/
-
-.netBar, .netSummaryBar {
- position: relative;
- border-right: 50px solid transparent;
-}
-
-.netResolvingBar {
- position: absolute;
- left: 0;
- top: 0;
- bottom: 0;
- background: #FFFFFF url(chrome://firebug/skin/netBarResolving.gif) repeat-x;
- z-index:60;
-}
-
-.netConnectingBar {
- position: absolute;
- left: 0;
- top: 0;
- bottom: 0;
- background: #FFFFFF url(chrome://firebug/skin/netBarConnecting.gif) repeat-x;
- z-index:50;
-}
-
-.netBlockingBar {
- position: absolute;
- left: 0;
- top: 0;
- bottom: 0;
- background: #FFFFFF url(chrome://firebug/skin/netBarWaiting.gif) repeat-x;
- z-index:40;
-}
-
-.netSendingBar {
- position: absolute;
- left: 0;
- top: 0;
- bottom: 0;
- background: #FFFFFF url(chrome://firebug/skin/netBarSending.gif) repeat-x;
- z-index:30;
-}
-
-.netWaitingBar {
- position: absolute;
- left: 0;
- top: 0;
- bottom: 0;
- background: #FFFFFF url(chrome://firebug/skin/netBarResponded.gif) repeat-x;
- z-index:20;
- min-width: 1px;
-}
-
-.netReceivingBar {
- position: absolute;
- left: 0;
- top: 0;
- bottom: 0;
- background: #38D63B url(chrome://firebug/skin/netBarLoading.gif) repeat-x;
- z-index:10;
-}
-
-.netWindowLoadBar,
-.netContentLoadBar {
- position: absolute;
- left: 0;
- top: 0;
- bottom: 0;
- width: 1px;
- background-color: red;
- z-index: 70;
- opacity: 0.5;
- display: none;
- margin-bottom:-1px;
-}
-
-.netContentLoadBar {
- background-color: Blue;
-}
-
-.netTimeLabel {
- -moz-box-sizing: padding-box;
- position: absolute;
- top: 1px;
- left: 100%;
- padding-left: 6px;
- color: #444444;
- min-width: 16px;
-}
-
-/*
- * Timing info tip is reusing net timeline styles to display the same
- * colors for individual request phases. Notice that the info tip must
- * respect also loaded and fromCache styles that also modify the
- * actual color. These are used both on the same element in case
- * of the tooltip.
- */
-.loaded .netReceivingBar,
-.loaded.netReceivingBar {
- background: #B6B6B6 url(chrome://firebug/skin/netBarLoaded.gif) repeat-x;
- border-color: #B6B6B6;
-}
-
-.fromCache .netReceivingBar,
-.fromCache.netReceivingBar {
- background: #D6D6D6 url(chrome://firebug/skin/netBarCached.gif) repeat-x;
- border-color: #D6D6D6;
-}
-
-.netSummaryRow .netTimeLabel,
-.loaded .netTimeLabel {
- background: transparent;
-}
-
-/************************************************************************************************/
-/* Time Info tip */
-
-.timeInfoTip {
- width: 150px;
- height: 40px
-}
-
-.timeInfoTipBar,
-.timeInfoTipEventBar {
- position: relative;
- display: block;
- margin: 0;
- opacity: 1;
- height: 15px;
- width: 4px;
-}
-
-.timeInfoTipEventBar {
- width: 1px !important;
-}
-
-.timeInfoTipCell.startTime {
- padding-right: 8px;
-}
-
-.timeInfoTipCell.elapsedTime {
- text-align: right;
- padding-right: 8px;
-}
-
-/************************************************************************************************/
-/* Size Info tip */
-
-.sizeInfoLabelCol {
- font-weight: bold;
- padding-right: 10px;
- font-family: Lucida Grande, Tahoma, sans-serif;
- font-size: 11px;
-}
-
-.sizeInfoSizeCol {
- font-weight: bold;
-}
-
-.sizeInfoDetailCol {
- color: gray;
- text-align: right;
-}
-
-.sizeInfoDescCol {
- font-style: italic;
-}
-
-/************************************************************************************************/
-/* Summary */
-
-.netSummaryRow .netReceivingBar {
- background: #BBBBBB;
- border: none;
-}
-
-.netSummaryLabel {
- color: #222222;
-}
-
-.netSummaryRow {
- background: #BBBBBB !important;
- font-weight: bold;
-}
-
-.netSummaryRow .netBar {
- border-right-color: #BBBBBB;
-}
-
-.netSummaryRow > .netCol {
- border-top: 1px solid #999999;
- border-bottom: 2px solid;
- -moz-border-bottom-colors: #EFEFEF #999999;
- padding-top: 1px;
- padding-bottom: 2px;
-}
-
-.netSummaryRow > .netHrefCol:hover {
- background: transparent !important;
-}
-
-.netCountLabel {
- padding-left: 18px;
-}
-
-.netTotalSizeCol {
- text-align: right;
- padding-right: 10px;
-}
-
-.netTotalTimeCol {
- text-align: right;
-}
-
-.netCacheSizeLabel {
- position: absolute;
- z-index: 1000;
- left: 0;
- top: 0;
-}
-
-/************************************************************************************************/
-
-.netLimitRow {
- background: rgb(255, 255, 225) !important;
- font-weight:normal;
- color: black;
- font-weight:normal;
-}
-
-.netLimitLabel {
- padding-left: 18px;
-}
-
-.netLimitRow > .netCol {
- border-bottom: 2px solid;
- -moz-border-bottom-colors: #EFEFEF #999999;
- vertical-align: middle !important;
- padding-top: 2px;
- padding-bottom: 2px;
-}
-
-.netLimitButton {
- font-size: 11px;
- padding-top: 1px;
- padding-bottom: 1px;
-}
-
-/************************************************************************************************/
-
-.netInfoCol {
- border-top: 1px solid #EEEEEE;
- background: url(chrome://firebug/skin/group.gif) repeat-x #FFFFFF;
-}
-
-.netInfoBody {
- margin: 10px 0 4px 10px;
-}
-
-.netInfoTabs {
- position: relative;
- padding-left: 17px;
-}
-
-.netInfoTab {
- position: relative;
- top: -3px;
- margin-top: 10px;
- padding: 4px 6px;
- border: 1px solid transparent;
- border-bottom: none;
- _border: none;
- font-weight: bold;
- color: #565656;
- cursor: pointer;
-}
-
-/*.netInfoTab:hover {
- cursor: pointer;
-}*/
-
-/* replaced by .netInfoTabSelected for IE6 support
-.netInfoTab[selected="true"] {
- cursor: default !important;
- border: 1px solid #D7D7D7 !important;
- border-bottom: none !important;
- -moz-border-radius: 4px 4px 0 0;
- background-color: #FFFFFF;
-}
-/**/
-.netInfoTabSelected {
- cursor: default !important;
- border: 1px solid #D7D7D7 !important;
- border-bottom: none !important;
- -moz-border-radius: 4px 4px 0 0;
- -webkit-border-radius: 4px 4px 0 0;
- border-radius: 4px 4px 0 0;
- background-color: #FFFFFF;
-}
-
-.logRow-netInfo.error .netInfoTitle {
- color: red;
-}
-
-.logRow-netInfo.loading .netInfoResponseText {
- font-style: italic;
- color: #888888;
-}
-
-.loading .netInfoResponseHeadersTitle {
- display: none;
-}
-
-.netInfoResponseSizeLimit {
- font-family: Lucida Grande, Tahoma, sans-serif;
- padding-top: 10px;
- font-size: 11px;
-}
-
-.netInfoText {
- display: none;
- margin: 0;
- border: 1px solid #D7D7D7;
- border-right: none;
- padding: 8px;
- background-color: #FFFFFF;
- font-family: Monaco, monospace;
- white-space: pre-wrap;
- /*overflow-x: auto; HTML is damaged in case of big (2-3MB) responses */
-}
-
-/* replaced by .netInfoTextSelected for IE6 support
-.netInfoText[selected="true"] {
- display: block;
-}
-/**/
-.netInfoTextSelected {
- display: block;
-}
-
-.netInfoParamName {
- padding-right: 10px;
- font-family: Lucida Grande, Tahoma, sans-serif;
- font-weight: bold;
- vertical-align: top;
- text-align: right;
- white-space: nowrap;
-}
-
-.netInfoPostText .netInfoParamName {
- width: 1px; /* Google Chrome need this otherwise the first column of
- the post variables table will be larger than expected */
-}
-
-.netInfoParamValue {
- width: 100%;
-}
-
-.netInfoHeadersText,
-.netInfoPostText,
-.netInfoPutText {
- padding-top: 0;
-}
-
-.netInfoHeadersGroup,
-.netInfoPostParams,
-.netInfoPostSource {
- margin-bottom: 4px;
- border-bottom: 1px solid #D7D7D7;
- padding-top: 8px;
- padding-bottom: 2px;
- font-family: Lucida Grande, Tahoma, sans-serif;
- font-weight: bold;
- color: #565656;
-}
-
-.netInfoPostParamsTable,
-.netInfoPostPartsTable,
-.netInfoPostJSONTable,
-.netInfoPostXMLTable,
-.netInfoPostSourceTable {
- margin-bottom: 10px;
- width: 100%;
-}
-
-.netInfoPostContentType {
- color: #bdbdbd;
- padding-left: 50px;
- font-weight: normal;
-}
-
-.netInfoHtmlPreview {
- border: 0;
- width: 100%;
- height:100%;
-}
-
-/************************************************************************************************/
-/* Request & Response Headers */
-
-.netHeadersViewSource {
- color: #bdbdbd;
- margin-left: 200px;
- font-weight: normal;
-}
-
-.netHeadersViewSource:hover {
- color: blue;
- cursor: pointer;
-}
-
-/************************************************************************************************/
-
-.netActivationRow,
-.netPageSeparatorRow {
- background: rgb(229, 229, 229) !important;
- font-weight: normal;
- color: black;
-}
-
-.netActivationLabel {
- background: url(chrome://firebug/skin/infoIcon.png) no-repeat 3px 2px;
- padding-left: 22px;
-}
-
-/************************************************************************************************/
-
-.netPageSeparatorRow {
- height: 5px !important;
-}
-
-.netPageSeparatorLabel {
- padding-left: 22px;
- height: 5px !important;
-}
-
-.netPageRow {
- background-color: rgb(255, 255, 255);
-}
-
-.netPageRow:hover {
- background: #EFEFEF;
-}
-
-.netPageLabel {
- padding: 1px 0 2px 18px !important;
- font-weight: bold;
-}
-
-/************************************************************************************************/
-
-.netActivationRow > .netCol {
- border-bottom: 2px solid;
- -moz-border-bottom-colors: #EFEFEF #999999;
- padding-top: 2px;
- padding-bottom: 3px;
-}
-/*
-.useA11y .panelNode-net .a11yFocus:focus,
-.useA11y .panelNode-net .focusRow:focus {
- outline-offset: -2px;
- background-color: #FFFFD6 !important;
-}
-
-.useA11y .panelNode-net .netHeaderCell:focus,
-.useA11y .panelNode-net :focus .netHeaderCell,
-.useA11y .panelNode-net :focus .netReceivingBar,
-.useA11y .netSummaryRow :focus .netBar,
-.useA11y .netSummaryRow:focus .netBar {
- background-color: #FFFFD6;
- background-image: none;
- border-color: #FFFFD6;
-}
-/**/
-
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/* Windows */
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-
-
-/************************************************************************************************/
-/* Twisties */
-
-.twisty,
-.logRow-errorMessage > .hasTwisty > .errorTitle,
-.logRow-log > .objectBox-array.hasTwisty,
-.logRow-spy .spyHead .spyTitle,
-.logGroup > .logRow,
-.memberRow.hasChildren > .memberLabelCell > .memberLabel,
-.hasHeaders .netHrefLabel,
-.netPageRow > .netCol > .netPageTitle {
- background-image: url(tree_open.gif);
- background-repeat: no-repeat;
- background-position: 2px 2px;
- min-height: 12px;
-}
-
-.logRow-errorMessage > .hasTwisty.opened > .errorTitle,
-.logRow-log > .objectBox-array.hasTwisty.opened,
-.logRow-spy.opened .spyHead .spyTitle,
-.logGroup.opened > .logRow,
-.memberRow.hasChildren.opened > .memberLabelCell > .memberLabel,
-.nodeBox.highlightOpen > .nodeLabel > .twisty,
-.nodeBox.open > .nodeLabel > .twisty,
-.netRow.opened > .netCol > .netHrefLabel,
-.netPageRow.opened > .netCol > .netPageTitle {
- background-image: url(tree_close.gif);
-}
-
-.twisty {
- background-position: 4px 4px;
-}
-
-
-
-/************************************************************************************************/
-/* Twisties IE6 */
-
-/* IE6 has problems with > operator, and multiple classes */
-
-* html .logRow-spy .spyHead .spyTitle,
-* html .logGroup .logGroupLabel,
-* html .hasChildren .memberLabelCell .memberLabel,
-* html .hasHeaders .netHrefLabel {
- background-image: url(tree_open.gif);
- background-repeat: no-repeat;
- background-position: 2px 2px;
-}
-
-* html .opened .spyHead .spyTitle,
-* html .opened .logGroupLabel,
-* html .opened .memberLabelCell .memberLabel {
- background-image: url(tree_close.gif);
- background-repeat: no-repeat;
- background-position: 2px 2px;
-}
-
-
-
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/* Console */
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-
-
-/* See license.txt for terms of usage */
-
-.panelNode-console {
- overflow-x: hidden;
-}
-
-.objectLink {
- text-decoration: none;
-}
-
-.objectLink:hover {
- cursor: pointer;
- text-decoration: underline;
-}
-
-.logRow {
- position: relative;
- margin: 0;
- border-bottom: 1px solid #D7D7D7;
- padding: 2px 4px 1px 6px;
- background-color: #FFFFFF;
- overflow: hidden !important; /* IE need this to avoid disappearing bug with collapsed logs */
-}
-
-.useA11y .logRow:focus {
- border-bottom: 1px solid #000000 !important;
- outline: none !important;
- background-color: #FFFFAD !important;
-}
-
-.useA11y .logRow:focus a.objectLink-sourceLink {
- background-color: #FFFFAD;
-}
-
-.useA11y .a11yFocus:focus, .useA11y .objectBox:focus {
- outline: 2px solid #FF9933;
- background-color: #FFFFAD;
-}
-
-.useA11y .objectBox-null:focus, .useA11y .objectBox-undefined:focus{
- background-color: #888888 !important;
-}
-
-.useA11y .logGroup.opened > .logRow {
- border-bottom: 1px solid #ffffff;
-}
-
-.logGroup {
- background: url(group.gif) repeat-x #FFFFFF;
- padding: 0 !important;
- border: none !important;
-}
-
-.logGroupBody {
- display: none;
- margin-left: 16px;
- border-left: 1px solid #D7D7D7;
- border-top: 1px solid #D7D7D7;
- background: #FFFFFF;
-}
-
-.logGroup > .logRow {
- background-color: transparent !important;
- font-weight: bold;
-}
-
-.logGroup.opened > .logRow {
- border-bottom: none;
-}
-
-.logGroup.opened > .logGroupBody {
- display: block;
-}
-
-/*****************************************************************************************/
-
-.logRow-command > .objectBox-text {
- font-family: Monaco, monospace;
- color: #0000FF;
- white-space: pre-wrap;
-}
-
-.logRow-info,
-.logRow-warn,
-.logRow-error,
-.logRow-assert,
-.logRow-warningMessage,
-.logRow-errorMessage {
- padding-left: 22px;
- background-repeat: no-repeat;
- background-position: 4px 2px;
-}
-
-.logRow-assert,
-.logRow-warningMessage,
-.logRow-errorMessage {
- padding-top: 0;
- padding-bottom: 0;
-}
-
-.logRow-info,
-.logRow-info .objectLink-sourceLink {
- background-color: #FFFFFF;
-}
-
-.logRow-warn,
-.logRow-warningMessage,
-.logRow-warn .objectLink-sourceLink,
-.logRow-warningMessage .objectLink-sourceLink {
- background-color: cyan;
-}
-
-.logRow-error,
-.logRow-assert,
-.logRow-errorMessage,
-.logRow-error .objectLink-sourceLink,
-.logRow-errorMessage .objectLink-sourceLink {
- background-color: LightYellow;
-}
-
-.logRow-error,
-.logRow-assert,
-.logRow-errorMessage {
- color: #FF0000;
-}
-
-.logRow-info {
- /*background-image: url(chrome://firebug/skin/infoIcon.png);*/
-}
-
-.logRow-warn,
-.logRow-warningMessage {
- /*background-image: url(chrome://firebug/skin/warningIcon.png);*/
-}
-
-.logRow-error,
-.logRow-assert,
-.logRow-errorMessage {
- /*background-image: url(chrome://firebug/skin/errorIcon.png);*/
-}
-
-/*****************************************************************************************/
-
-.objectBox-string,
-.objectBox-text,
-.objectBox-number,
-.objectLink-element,
-.objectLink-textNode,
-.objectLink-function,
-.objectBox-stackTrace,
-.objectLink-profile {
- font-family: Monaco, monospace;
-}
-
-.objectBox-string,
-.objectBox-text,
-.objectLink-textNode {
- white-space: pre-wrap;
-}
-
-.objectBox-number,
-.objectLink-styleRule,
-.objectLink-element,
-.objectLink-textNode {
- color: #000088;
-}
-
-.objectBox-string {
- color: #FF0000;
-}
-
-.objectLink-function,
-.objectBox-stackTrace,
-.objectLink-profile {
- color: DarkGreen;
-}
-
-.objectBox-null,
-.objectBox-undefined {
- padding: 0 2px;
- border: 1px solid #666666;
- background-color: #888888;
- color: #FFFFFF;
-}
-
-.objectBox-exception {
- padding: 0 2px 0 18px;
- /*background: url(chrome://firebug/skin/errorIcon-sm.png) no-repeat 0 0;*/
- color: red;
-}
-
-.objectLink-sourceLink {
- position: absolute;
- right: 4px;
- top: 2px;
- padding-left: 8px;
- font-family: Lucida Grande, sans-serif;
- font-weight: bold;
- color: #0000FF;
-}
-
-/************************************************************************************************/
-
-.errorTitle {
- margin-top: 0px;
- margin-bottom: 1px;
- padding-top: 2px;
- padding-bottom: 2px;
-}
-
-.errorTrace {
- margin-left: 17px;
-}
-
-.errorSourceBox {
- margin: 2px 0;
-}
-
-.errorSource-none {
- display: none;
-}
-
-.errorSource-syntax > .errorBreak {
- visibility: hidden;
-}
-
-.errorSource {
- cursor: pointer;
- font-family: Monaco, monospace;
- color: DarkGreen;
-}
-
-.errorSource:hover {
- text-decoration: underline;
-}
-
-.errorBreak {
- cursor: pointer;
- display: none;
- margin: 0 6px 0 0;
- width: 13px;
- height: 14px;
- vertical-align: bottom;
- /*background: url(chrome://firebug/skin/breakpoint.png) no-repeat;*/
- opacity: 0.1;
-}
-
-.hasBreakSwitch .errorBreak {
- display: inline;
-}
-
-.breakForError .errorBreak {
- opacity: 1;
-}
-
-.assertDescription {
- margin: 0;
-}
-
-/************************************************************************************************/
-
-.logRow-profile > .logRow > .objectBox-text {
- font-family: Lucida Grande, Tahoma, sans-serif;
- color: #000000;
-}
-
-.logRow-profile > .logRow > .objectBox-text:last-child {
- color: #555555;
- font-style: italic;
-}
-
-.logRow-profile.opened > .logRow {
- padding-bottom: 4px;
-}
-
-.profilerRunning > .logRow {
- /*background: transparent url(chrome://firebug/skin/loading_16.gif) no-repeat 2px 0 !important;*/
- padding-left: 22px !important;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.profileSizer {
- width:100%;
- overflow-x:auto;
- overflow-y: scroll;
-}
-
-.profileTable {
- border-bottom: 1px solid #D7D7D7;
- padding: 0 0 4px 0;
-}
-
-.profileTable tr[odd="1"] {
- background-color: #F5F5F5;
- vertical-align:middle;
-}
-
-.profileTable a {
- vertical-align:middle;
-}
-
-.profileTable td {
- padding: 1px 4px 0 4px;
-}
-
-.headerCell {
- cursor: pointer;
- -moz-user-select: none;
- border-bottom: 1px solid #9C9C9C;
- padding: 0 !important;
- font-weight: bold;
- /*background: #BBBBBB url(chrome://firebug/skin/tableHeader.gif) repeat-x;*/
-}
-
-.headerCellBox {
- padding: 2px 4px;
- border-left: 1px solid #D9D9D9;
- border-right: 1px solid #9C9C9C;
-}
-
-.headerCell:hover:active {
- /*background: #959595 url(chrome://firebug/skin/tableHeaderActive.gif) repeat-x;*/
-}
-
-.headerSorted {
- /*background: #7D93B2 url(chrome://firebug/skin/tableHeaderSorted.gif) repeat-x;*/
-}
-
-.headerSorted > .headerCellBox {
- border-right-color: #6B7C93;
- /*background: url(chrome://firebug/skin/arrowDown.png) no-repeat right;*/
-}
-
-.headerSorted.sortedAscending > .headerCellBox {
- /*background-image: url(chrome://firebug/skin/arrowUp.png);*/
-}
-
-.headerSorted:hover:active {
- /*background: #536B90 url(chrome://firebug/skin/tableHeaderSortedActive.gif) repeat-x;*/
-}
-
-.linkCell {
- text-align: right;
-}
-
-.linkCell > .objectLink-sourceLink {
- position: static;
-}
-
-/*****************************************************************************************/
-
-.logRow-stackTrace {
- padding-top: 0;
- background: #f8f8f8;
-}
-
-.logRow-stackTrace > .objectBox-stackFrame {
- position: relative;
- padding-top: 2px;
-}
-
-/************************************************************************************************/
-
-.objectLink-object {
- font-family: Lucida Grande, sans-serif;
- font-weight: bold;
- color: DarkGreen;
- white-space: pre-wrap;
-}
-
-/* xxxpedro reps object representation .................................... */
-.objectProp-object {
- color: DarkGreen;
-}
-
-.objectProps {
- color: #000;
- font-weight: normal;
-}
-
-.objectPropName {
- /*font-style: italic;*/
- color: #777;
-}
-
-/*
-.objectProps .objectProp-string,
-.objectProps .objectProp-number,
-.objectProps .objectProp-object
-{
- font-style: italic;
-}
-/**/
-
-.objectProps .objectProp-string
-{
- /*font-family: Monaco, monospace;*/
- color: #f55;
-}
-.objectProps .objectProp-number
-{
- /*font-family: Monaco, monospace;*/
- color: #55a;
-}
-.objectProps .objectProp-object
-{
- /*font-family: Lucida Grande,sans-serif;*/
- color: #585;
-}
-/* xxxpedro reps object representation .................................... */
-
-/************************************************************************************************/
-
-.selectorTag,
-.selectorId,
-.selectorClass {
- font-family: Monaco, monospace;
- font-weight: normal;
-}
-
-.selectorTag {
- color: #0000FF;
-}
-
-.selectorId {
- color: DarkBlue;
-}
-
-.selectorClass {
- color: red;
-}
-
-.selectorHidden > .selectorTag {
- color: #5F82D9;
-}
-
-.selectorHidden > .selectorId {
- color: #888888;
-}
-
-.selectorHidden > .selectorClass {
- color: #D86060;
-}
-
-.selectorValue {
- font-family: Lucida Grande, sans-serif;
- font-style: italic;
- color: #555555;
-}
-
-/*****************************************************************************************/
-
-.panelNode.searching .logRow {
- display: none;
-}
-
-.logRow.matched {
- display: block !important;
-}
-
-.logRow.matching {
- position: absolute;
- left: -1000px;
- top: -1000px;
- max-width: 0;
- max-height: 0;
- overflow: hidden;
-}
-
-/*****************************************************************************************/
-
-.objectLeftBrace,
-.objectRightBrace,
-.objectEqual,
-.objectComma,
-.arrayLeftBracket,
-.arrayRightBracket,
-.arrayComma {
- font-family: Monaco, monospace;
-}
-
-.objectLeftBrace,
-.objectRightBrace,
-.arrayLeftBracket,
-.arrayRightBracket {
- font-weight: bold;
-}
-
-.objectLeftBrace,
-.arrayLeftBracket {
- margin-right: 4px;
-}
-
-.objectRightBrace,
-.arrayRightBracket {
- margin-left: 4px;
-}
-
-/*****************************************************************************************/
-
-.logRow-dir {
- padding: 0;
-}
-
-/************************************************************************************************/
-
-/*
-.logRow-errorMessage > .hasTwisty > .errorTitle,
-.logRow-spy .spyHead .spyTitle,
-.logGroup > .logRow
-*/
-.logRow-errorMessage .hasTwisty .errorTitle,
-.logRow-spy .spyHead .spyTitle,
-.logGroup .logRow {
- cursor: pointer;
- padding-left: 18px;
- background-repeat: no-repeat;
- background-position: 3px 3px;
-}
-
-.logRow-errorMessage > .hasTwisty > .errorTitle {
- background-position: 2px 3px;
-}
-
-.logRow-errorMessage > .hasTwisty > .errorTitle:hover,
-.logRow-spy .spyHead .spyTitle:hover,
-.logGroup > .logRow:hover {
- text-decoration: underline;
-}
-
-/*****************************************************************************************/
-
-.logRow-spy {
- padding: 0 !important;
-}
-
-.logRow-spy,
-.logRow-spy .objectLink-sourceLink {
- background: url(group.gif) repeat-x #FFFFFF;
- padding-right: 4px;
- right: 0;
-}
-
-.logRow-spy.opened {
- padding-bottom: 4px;
- border-bottom: none;
-}
-
-.spyTitle {
- color: #000000;
- font-weight: bold;
- -moz-box-sizing: padding-box;
- overflow: hidden;
- z-index: 100;
- padding-left: 18px;
-}
-
-.spyCol {
- padding: 0;
- white-space: nowrap;
- height: 16px;
-}
-
-.spyTitleCol:hover > .objectLink-sourceLink,
-.spyTitleCol:hover > .spyTime,
-.spyTitleCol:hover > .spyStatus,
-.spyTitleCol:hover > .spyTitle {
- display: none;
-}
-
-.spyFullTitle {
- display: none;
- -moz-user-select: none;
- max-width: 100%;
- background-color: Transparent;
-}
-
-.spyTitleCol:hover > .spyFullTitle {
- display: block;
-}
-
-.spyStatus {
- padding-left: 10px;
- color: rgb(128, 128, 128);
-}
-
-.spyTime {
- margin-left:4px;
- margin-right:4px;
- color: rgb(128, 128, 128);
-}
-
-.spyIcon {
- margin-right: 4px;
- margin-left: 4px;
- width: 16px;
- height: 16px;
- vertical-align: middle;
- background: transparent no-repeat 0 0;
- display: none;
-}
-
-.loading .spyHead .spyRow .spyIcon {
- background-image: url(loading_16.gif);
- display: block;
-}
-
-.logRow-spy.loaded:not(.error) .spyHead .spyRow .spyIcon {
- width: 0;
- margin: 0;
-}
-
-.logRow-spy.error .spyHead .spyRow .spyIcon {
- background-image: url(errorIcon-sm.png);
- display: block;
- background-position: 2px 2px;
-}
-
-.logRow-spy .spyHead .netInfoBody {
- display: none;
-}
-
-.logRow-spy.opened .spyHead .netInfoBody {
- margin-top: 10px;
- display: block;
-}
-
-.logRow-spy.error .spyTitle,
-.logRow-spy.error .spyStatus,
-.logRow-spy.error .spyTime {
- color: red;
-}
-
-.logRow-spy.loading .spyResponseText {
- font-style: italic;
- color: #888888;
-}
-
-/************************************************************************************************/
-
-.caption {
- font-family: Lucida Grande, Tahoma, sans-serif;
- font-weight: bold;
- color: #444444;
-}
-
-.warning {
- padding: 10px;
- font-family: Lucida Grande, Tahoma, sans-serif;
- font-weight: bold;
- color: #888888;
-}
-
-
-
-
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/* DOM */
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-
-
-/* See license.txt for terms of usage */
-
-.panelNode-dom {
- overflow-x: hidden !important;
-}
-
-.domTable {
- font-size: 1em;
- width: 100%;
- table-layout: fixed;
- background: #fff;
-}
-
-.domTableIE {
- width: auto;
-}
-
-.memberLabelCell {
- padding: 2px 0 2px 0;
- vertical-align: top;
-}
-
-.memberValueCell {
- padding: 1px 0 1px 5px;
- display: block;
- overflow: hidden;
-}
-
-.memberLabel {
- display: block;
- cursor: default;
- -moz-user-select: none;
- overflow: hidden;
- /*position: absolute;*/
- padding-left: 18px;
- /*max-width: 30%;*/
- /*white-space: nowrap;*/
- background-color: #FFFFFF;
- text-decoration: none;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.memberRow.hasChildren .memberLabelCell .memberLabel:hover {
- cursor: pointer;
- color: blue;
- text-decoration: underline;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.userLabel {
- color: #000000;
- font-weight: bold;
-}
-
-.userClassLabel {
- color: #E90000;
- font-weight: bold;
-}
-
-.userFunctionLabel {
- color: #025E2A;
- font-weight: bold;
-}
-
-.domLabel {
- color: #000000;
-}
-
-.domFunctionLabel {
- color: #025E2A;
-}
-
-.ordinalLabel {
- color: SlateBlue;
- font-weight: bold;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-.scopesRow {
- padding: 2px 18px;
- background-color: LightYellow;
- border-bottom: 5px solid #BEBEBE;
- color: #666666;
-}
-.scopesLabel {
- background-color: LightYellow;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.watchEditCell {
- padding: 2px 18px;
- background-color: LightYellow;
- border-bottom: 1px solid #BEBEBE;
- color: #666666;
-}
-
-.editor-watchNewRow,
-.editor-memberRow {
- font-family: Monaco, monospace !important;
-}
-
-.editor-memberRow {
- padding: 1px 0 !important;
-}
-
-.editor-watchRow {
- padding-bottom: 0 !important;
-}
-
-.watchRow > .memberLabelCell {
- font-family: Monaco, monospace;
- padding-top: 1px;
- padding-bottom: 1px;
-}
-
-.watchRow > .memberLabelCell > .memberLabel {
- background-color: transparent;
-}
-
-.watchRow > .memberValueCell {
- padding-top: 2px;
- padding-bottom: 2px;
-}
-
-.watchRow > .memberLabelCell,
-.watchRow > .memberValueCell {
- background-color: #F5F5F5;
- border-bottom: 1px solid #BEBEBE;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.watchToolbox {
- z-index: 2147483647;
- position: absolute;
- right: 0;
- padding: 1px 2px;
-}
-
-
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/*************************************************************************************************/
-/* FROM ORIGINAL FIREBUG */
-
-
-
-
-/************************************************************************************************
- CSS Not organized
-*************************************************************************************************/
-#fbConsole {
- overflow-x: hidden !important;
-}
-
-#fbCSS {
- font: 1em Monaco, monospace;
- padding: 0 7px;
-}
-
-#fbstylesheetButtons select, #fbScriptButtons select {
- font: 11px Lucida Grande, Tahoma, sans-serif;
- margin-top: 1px;
- padding-left: 3px;
- background: #fafafa;
- border: 1px inset #fff;
- width: 220px;
- outline: none;
-}
-
-.Selector { margin-top:10px }
-.CSSItem {margin-left: 4% }
-.CSSText { padding-left:20px; }
-.CSSProperty { color:#005500; }
-.CSSValue { padding-left:5px; color:#000088; }
-
-
-/************************************************************************************************
- Not organized
-*************************************************************************************************/
-
-#fbHTMLStatusBar {
- display: inline;
-}
-
-.fbToolbarButtons {
- display: none;
-}
-
-.fbStatusSeparator{
- display: block;
- float: left;
- padding-top: 4px;
-}
-
-#fbStatusBarBox {
- display: none;
-}
-
-#fbToolbarContent {
- display: block;
- position: absolute;
- _position: absolute;
- top: 0;
- padding-top: 4px;
- height: 23px;
- clip: rect(0, 2048px, 27px, 0);
-}
-
-.fbTabMenuTarget {
- display: none !important;
- float: left;
- width: 10px;
- height: 10px;
- margin-top: 6px;
- background: url(tabMenuTarget.png);
-}
-
-.fbTabMenuTarget:hover {
- background: url(tabMenuTargetHover.png);
-}
-
-.fbShadow {
- float: left;
- background: url(shadowAlpha.png) no-repeat bottom right !important;
- background: url(shadow2.gif) no-repeat bottom right;
- margin: 10px 0 0 10px !important;
- margin: 10px 0 0 5px;
-}
-
-.fbShadowContent {
- display: block;
- position: relative;
- background-color: #fff;
- border: 1px solid #a9a9a9;
- top: -6px;
- left: -6px;
-}
-
-.fbMenu {
- display: none;
- position: absolute;
- font-size: 11px;
- line-height: 13px;
- z-index: 2147483647;
-}
-
-.fbMenuContent {
- padding: 2px;
-}
-
-.fbMenuSeparator {
- display: block;
- position: relative;
- padding: 1px 18px 0;
- text-decoration: none;
- color: #000;
- cursor: default;
- background: #ACA899;
- margin: 4px 0;
-}
-
-.fbMenuOption
-{
- display: block;
- position: relative;
- padding: 2px 18px;
- text-decoration: none;
- color: #000;
- cursor: default;
-}
-
-.fbMenuOption:hover
-{
- color: #fff;
- background: #316AC5;
-}
-
-.fbMenuGroup {
- background: transparent url(tabMenuPin.png) no-repeat right 0;
-}
-
-.fbMenuGroup:hover {
- background: #316AC5 url(tabMenuPin.png) no-repeat right -17px;
-}
-
-.fbMenuGroupSelected {
- color: #fff;
- background: #316AC5 url(tabMenuPin.png) no-repeat right -17px;
-}
-
-.fbMenuChecked {
- background: transparent url(tabMenuCheckbox.png) no-repeat 4px 0;
-}
-
-.fbMenuChecked:hover {
- background: #316AC5 url(tabMenuCheckbox.png) no-repeat 4px -17px;
-}
-
-.fbMenuRadioSelected {
- background: transparent url(tabMenuRadio.png) no-repeat 4px 0;
-}
-
-.fbMenuRadioSelected:hover {
- background: #316AC5 url(tabMenuRadio.png) no-repeat 4px -17px;
-}
-
-.fbMenuShortcut {
- padding-right: 85px;
-}
-
-.fbMenuShortcutKey {
- position: absolute;
- right: 0;
- top: 2px;
- width: 77px;
-}
-
-#fbFirebugMenu {
- top: 22px;
- left: 0;
-}
-
-.fbMenuDisabled {
- color: #ACA899 !important;
-}
-
-#fbFirebugSettingsMenu {
- left: 245px;
- top: 99px;
-}
-
-#fbConsoleMenu {
- top: 42px;
- left: 48px;
-}
-
-.fbIconButton {
- display: block;
-}
-
-.fbIconButton {
- display: block;
-}
-
-.fbIconButton {
- display: block;
- float: left;
- height: 20px;
- width: 20px;
- color: #000;
- margin-right: 2px;
- text-decoration: none;
- cursor: default;
-}
-
-.fbIconButton:hover {
- position: relative;
- top: -1px;
- left: -1px;
- margin-right: 0;
- _margin-right: 1px;
- color: #333;
- border: 1px solid #fff;
- border-bottom: 1px solid #bbb;
- border-right: 1px solid #bbb;
-}
-
-.fbIconPressed {
- position: relative;
- margin-right: 0;
- _margin-right: 1px;
- top: 0 !important;
- left: 0 !important;
- height: 19px;
- color: #333 !important;
- border: 1px solid #bbb !important;
- border-bottom: 1px solid #cfcfcf !important;
- border-right: 1px solid #ddd !important;
-}
-
-
-
-/************************************************************************************************
- Error Popup
-*************************************************************************************************/
-#fbErrorPopup {
- position: absolute;
- right: 0;
- bottom: 0;
- height: 19px;
- width: 75px;
- background: url(sprite.png) #f1f2ee 0 0;
- z-index: 999;
-}
-
-#fbErrorPopupContent {
- position: absolute;
- right: 0;
- top: 1px;
- height: 18px;
- width: 75px;
- _width: 74px;
- border-left: 1px solid #aca899;
-}
-
-#fbErrorIndicator {
- position: absolute;
- top: 2px;
- right: 5px;
-}
-
-
-
-
-
-
-
-
-
-
-.fbBtnInspectActive {
- background: #aaa;
- color: #fff !important;
-}
-
-/************************************************************************************************
- General
-*************************************************************************************************/
-.fbBody {
- margin: 0;
- padding: 0;
- overflow: hidden;
-
- font-family: Lucida Grande, Tahoma, sans-serif;
- font-size: 11px;
- background: #fff;
-}
-
-.clear {
- clear: both;
-}
-
-/************************************************************************************************
- Mini Chrome
-*************************************************************************************************/
-#fbMiniChrome {
- display: none;
- right: 0;
- height: 27px;
- background: url(sprite.png) #f1f2ee 0 0;
- margin-left: 1px;
-}
-
-#fbMiniContent {
- display: block;
- position: relative;
- left: -1px;
- right: 0;
- top: 1px;
- height: 25px;
- border-left: 1px solid #aca899;
-}
-
-#fbToolbarSearch {
- float: right;
- border: 1px solid #ccc;
- margin: 0 5px 0 0;
- background: #fff url(search.png) no-repeat 4px 2px !important;
- background: #fff url(search.gif) no-repeat 4px 2px;
- padding-left: 20px;
- font-size: 11px;
-}
-
-#fbToolbarErrors {
- float: right;
- margin: 1px 4px 0 0;
- font-size: 11px;
-}
-
-#fbLeftToolbarErrors {
- float: left;
- margin: 7px 0px 0 5px;
- font-size: 11px;
-}
-
-.fbErrors {
- padding-left: 20px;
- height: 14px;
- background: url(errorIcon.png) no-repeat !important;
- background: url(errorIcon.gif) no-repeat;
- color: #f00;
- font-weight: bold;
-}
-
-#fbMiniErrors {
- display: inline;
- display: none;
- float: right;
- margin: 5px 2px 0 5px;
-}
-
-#fbMiniIcon {
- float: right;
- margin: 3px 4px 0;
- height: 20px;
- width: 20px;
- float: right;
- background: url(sprite.png) 0 -135px;
- cursor: pointer;
-}
-
-
-/************************************************************************************************
- Master Layout
-*************************************************************************************************/
-#fbChrome {
- font-family: Lucida Grande, Tahoma, sans-serif;
- font-size: 11px;
- position: absolute;
- _position: static;
- top: 0;
- left: 0;
- height: 100%;
- width: 100%;
- border-collapse: collapse;
- border-spacing: 0;
- background: #fff;
- overflow: hidden;
-}
-
-#fbChrome > tbody > tr > td {
- padding: 0;
-}
-
-#fbTop {
- height: 49px;
-}
-
-#fbToolbar {
- background: url(sprite.png) #f1f2ee 0 0;
- height: 27px;
- font-size: 11px;
- line-height: 13px;
-}
-
-#fbPanelBarBox {
- background: url(sprite.png) #dbd9c9 0 -27px;
- height: 22px;
-}
-
-#fbContent {
- height: 100%;
- vertical-align: top;
-}
-
-#fbBottom {
- height: 18px;
- background: #fff;
-}
-
-/************************************************************************************************
- Sub-Layout
-*************************************************************************************************/
-
-/* fbToolbar
-*************************************************************************************************/
-#fbToolbarIcon {
- float: left;
- padding: 0 5px 0;
-}
-
-#fbToolbarIcon a {
- background: url(sprite.png) 0 -135px;
-}
-
-#fbToolbarButtons {
- padding: 0 2px 0 5px;
-}
-
-#fbToolbarButtons {
- padding: 0 2px 0 5px;
-}
-/*
-#fbStatusBarBox a {
- text-decoration: none;
- display: block;
- float: left;
- color: #000;
- padding: 4px 5px;
- margin: 0 0 0 1px;
- cursor: default;
-}
-
-#fbStatusBarBox a:hover {
- color: #333;
- padding: 3px 4px;
- border: 1px solid #fff;
- border-bottom: 1px solid #bbb;
- border-right: 1px solid #bbb;
-}
-/**/
-
-.fbButton {
- text-decoration: none;
- display: block;
- float: left;
- color: #000;
- padding: 4px 6px 4px 7px;
- cursor: default;
-}
-
-.fbButton:hover {
- color: #333;
- background: #f5f5ef url(buttonBg.png);
- padding: 3px 5px 3px 6px;
- border: 1px solid #fff;
- border-bottom: 1px solid #bbb;
- border-right: 1px solid #bbb;
-}
-
-.fbBtnPressed {
- background: #e3e3db url(buttonBgHover.png) !important;
- padding: 3px 4px 2px 6px !important;
- margin: 1px 0 0 1px !important;
- border: 1px solid #ACA899 !important;
- border-color: #ACA899 #ECEBE3 #ECEBE3 #ACA899 !important;
-}
-
-#fbStatusBarBox {
- top: 4px;
- cursor: default;
-}
-
-.fbToolbarSeparator {
- overflow: hidden;
- border: 1px solid;
- border-color: transparent #fff transparent #777;
- _border-color: #eee #fff #eee #777;
- height: 7px;
- margin: 6px 3px;
- float: left;
-}
-
-.fbBtnSelected {
- font-weight: bold;
-}
-
-.fbStatusBar {
- color: #aca899;
-}
-
-.fbStatusBar a {
- text-decoration: none;
- color: black;
-}
-
-.fbStatusBar a:hover {
- color: blue;
- cursor: pointer;
-}
-
-
-#fbWindowButtons {
- position: absolute;
- white-space: nowrap;
- right: 0;
- top: 0;
- height: 17px;
- width: 48px;
- padding: 5px;
- z-index: 6;
- background: url(sprite.png) #f1f2ee 0 0;
-}
-
-/* fbPanelBarBox
-*************************************************************************************************/
-
-#fbPanelBar1 {
- width: 1024px; /* fixed width to avoid tabs breaking line */
- z-index: 8;
- left: 0;
- white-space: nowrap;
- background: url(sprite.png) #dbd9c9 0 -27px;
- position: absolute;
- left: 4px;
-}
-
-#fbPanelBar2Box {
- background: url(sprite.png) #dbd9c9 0 -27px;
- position: absolute;
- height: 22px;
- width: 300px; /* fixed width to avoid tabs breaking line */
- z-index: 9;
- right: 0;
-}
-
-#fbPanelBar2 {
- position: absolute;
- width: 290px; /* fixed width to avoid tabs breaking line */
- height: 22px;
- padding-left: 4px;
-}
-
-/* body
-*************************************************************************************************/
-.fbPanel {
- display: none;
-}
-
-#fbPanelBox1, #fbPanelBox2 {
- max-height: inherit;
- height: 100%;
- font-size: 1em;
-}
-
-#fbPanelBox2 {
- background: #fff;
-}
-
-#fbPanelBox2 {
- width: 300px;
- background: #fff;
-}
-
-#fbPanel2 {
- margin-left: 6px;
- background: #fff;
-}
-
-#fbLargeCommandLine {
- display: none;
- position: absolute;
- z-index: 9;
- top: 27px;
- right: 0;
- width: 294px;
- height: 201px;
- border-width: 0;
- margin: 0;
- padding: 2px 0 0 2px;
- resize: none;
- outline: none;
- font-size: 11px;
- overflow: auto;
- border-top: 1px solid #B9B7AF;
- _right: -1px;
- _border-left: 1px solid #fff;
-}
-
-#fbLargeCommandButtons {
- display: none;
- background: #ECE9D8;
- bottom: 0;
- right: 0;
- width: 294px;
- height: 21px;
- padding-top: 1px;
- position: fixed;
- border-top: 1px solid #ACA899;
- z-index: 9;
-}
-
-#fbSmallCommandLineIcon {
- background: url(down.png) no-repeat;
- position: absolute;
- right: 2px;
- bottom: 3px;
-
- z-index: 99;
-}
-
-#fbSmallCommandLineIcon:hover {
- background: url(downHover.png) no-repeat;
-}
-
-.hide {
- overflow: hidden !important;
- position: fixed !important;
- display: none !important;
- visibility: hidden !important;
-}
-
-/* fbBottom
-*************************************************************************************************/
-
-#fbCommand {
- height: 18px;
-}
-
-#fbCommandBox {
- position: fixed;
- _position: absolute;
- width: 100%;
- height: 18px;
- bottom: 0;
- overflow: hidden;
- z-index: 9;
- background: #fff;
- border: 0;
- border-top: 1px solid #ccc;
-}
-
-#fbCommandIcon {
- position: absolute;
- color: #00f;
- top: 2px;
- left: 6px;
- display: inline;
- font: 11px Monaco, monospace;
- z-index: 10;
-}
-
-#fbCommandLine {
- position: absolute;
- width: 100%;
- top: 0;
- left: 0;
- border: 0;
- margin: 0;
- padding: 2px 0 2px 32px;
- font: 11px Monaco, monospace;
- z-index: 9;
- outline: none;
-}
-
-#fbLargeCommandLineIcon {
- background: url(up.png) no-repeat;
- position: absolute;
- right: 1px;
- bottom: 1px;
- z-index: 10;
-}
-
-#fbLargeCommandLineIcon:hover {
- background: url(upHover.png) no-repeat;
-}
-
-div.fbFitHeight {
- overflow: auto;
- position: relative;
-}
-
-
-/************************************************************************************************
- Layout Controls
-*************************************************************************************************/
-
-/* fbToolbar buttons
-*************************************************************************************************/
-.fbSmallButton {
- overflow: hidden;
- width: 16px;
- height: 16px;
- display: block;
- text-decoration: none;
- cursor: default;
-}
-
-#fbWindowButtons .fbSmallButton {
- float: right;
-}
-
-#fbWindow_btClose {
- background: url(min.png);
-}
-
-#fbWindow_btClose:hover {
- background: url(minHover.png);
-}
-
-#fbWindow_btDetach {
- background: url(detach.png);
-}
-
-#fbWindow_btDetach:hover {
- background: url(detachHover.png);
-}
-
-#fbWindow_btDeactivate {
- background: url(off.png);
-}
-
-#fbWindow_btDeactivate:hover {
- background: url(offHover.png);
-}
-
-
-/* fbPanelBarBox tabs
-*************************************************************************************************/
-.fbTab {
- text-decoration: none;
- display: none;
- float: left;
- width: auto;
- float: left;
- cursor: default;
- font-family: Lucida Grande, Tahoma, sans-serif;
- font-size: 11px;
- line-height: 13px;
- font-weight: bold;
- height: 22px;
- color: #565656;
-}
-
-.fbPanelBar span {
- /*display: block; TODO: safe to remove this? */
- float: left;
-}
-
-.fbPanelBar .fbTabL,.fbPanelBar .fbTabR {
- height: 22px;
- width: 8px;
-}
-
-.fbPanelBar .fbTabText {
- padding: 4px 1px 0;
-}
-
-a.fbTab:hover {
- background: url(sprite.png) 0 -73px;
-}
-
-a.fbTab:hover .fbTabL {
- background: url(sprite.png) -16px -96px;
-}
-
-a.fbTab:hover .fbTabR {
- background: url(sprite.png) -24px -96px;
-}
-
-.fbSelectedTab {
- background: url(sprite.png) #f1f2ee 0 -50px !important;
- color: #000;
-}
-
-.fbSelectedTab .fbTabL {
- background: url(sprite.png) 0 -96px !important;
-}
-
-.fbSelectedTab .fbTabR {
- background: url(sprite.png) -8px -96px !important;
-}
-
-/* splitters
-*************************************************************************************************/
-#fbHSplitter {
- position: fixed;
- _position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- height: 5px;
- overflow: hidden;
- cursor: n-resize !important;
- background: url(pixel_transparent.gif);
- z-index: 9;
-}
-
-#fbHSplitter.fbOnMovingHSplitter {
- height: 100%;
- z-index: 100;
-}
-
-.fbVSplitter {
- background: #ece9d8;
- color: #000;
- border: 1px solid #716f64;
- border-width: 0 1px;
- border-left-color: #aca899;
- width: 4px;
- cursor: e-resize;
- overflow: hidden;
- right: 294px;
- text-decoration: none;
- z-index: 10;
- position: absolute;
- height: 100%;
- top: 27px;
-}
-
-/************************************************************************************************/
-div.lineNo {
- font: 1em/1.4545em Monaco, monospace;
- position: relative;
- float: left;
- top: 0;
- left: 0;
- margin: 0 5px 0 0;
- padding: 0 5px 0 10px;
- background: #eee;
- color: #888;
- border-right: 1px solid #ccc;
- text-align: right;
-}
-
-.sourceBox {
- position: absolute;
-}
-
-.sourceCode {
- font: 1em Monaco, monospace;
- overflow: hidden;
- white-space: pre;
- display: inline;
-}
-
-/************************************************************************************************/
-.nodeControl {
- margin-top: 3px;
- margin-left: -14px;
- float: left;
- width: 9px;
- height: 9px;
- overflow: hidden;
- cursor: default;
- background: url(tree_open.gif);
- _float: none;
- _display: inline;
- _position: absolute;
-}
-
-div.nodeMaximized {
- background: url(tree_close.gif);
-}
-
-div.objectBox-element {
- padding: 1px 3px;
-}
-.objectBox-selector{
- cursor: default;
-}
-
-.selectedElement{
- background: highlight;
- /* background: url(roundCorner.svg); Opera */
- color: #fff !important;
-}
-.selectedElement span{
- color: #fff !important;
-}
-
-/* IE6 need this hack */
-* html .selectedElement {
- position: relative;
-}
-
-/* Webkit CSS Hack - bug in "highlight" named color */
-@media screen and (-webkit-min-device-pixel-ratio:0) {
- .selectedElement{
- background: #316AC5;
- color: #fff !important;
- }
-}
-
-/************************************************************************************************/
-/************************************************************************************************/
-.logRow * {
- font-size: 1em;
-}
-
-/* TODO: remove this? */
-/* TODO: xxxpedro - IE need this in windowless mode (cnn.com) check if the issue is related to
-position. if so, override it at chrome.js initialization when creating the div */
-.logRow {
- position: relative;
- border-bottom: 1px solid #D7D7D7;
- padding: 2px 4px 1px 6px;
- zbackground-color: #FFFFFF;
-}
-/**/
-
-.logRow-command {
- font-family: Monaco, monospace;
- color: blue;
-}
-
-.objectBox-string,
-.objectBox-text,
-.objectBox-number,
-.objectBox-function,
-.objectLink-element,
-.objectLink-textNode,
-.objectLink-function,
-.objectBox-stackTrace,
-.objectLink-profile {
- font-family: Monaco, monospace;
-}
-
-.objectBox-null {
- padding: 0 2px;
- border: 1px solid #666666;
- background-color: #888888;
- color: #FFFFFF;
-}
-
-.objectBox-string {
- color: red;
-
- /* TODO: xxxpedro make long strings break line */
- /*white-space: pre; */
-}
-
-.objectBox-number {
- color: #000088;
-}
-
-.objectBox-function {
- color: DarkGreen;
-}
-
-.objectBox-object {
- color: DarkGreen;
- font-weight: bold;
- font-family: Lucida Grande, sans-serif;
-}
-
-.objectBox-array {
- color: #000;
-}
-
-/************************************************************************************************/
-.logRow-info,.logRow-error,.logRow-warn {
- background: #fff no-repeat 2px 2px;
- padding-left: 20px;
- padding-bottom: 3px;
-}
-
-.logRow-info {
- background-image: url(infoIcon.png) !important;
- background-image: url(infoIcon.gif);
-}
-
-.logRow-warn {
- background-color: cyan;
- background-image: url(warningIcon.png) !important;
- background-image: url(warningIcon.gif);
-}
-
-.logRow-error {
- background-color: LightYellow;
- background-image: url(errorIcon.png) !important;
- background-image: url(errorIcon.gif);
- color: #f00;
-}
-
-.errorMessage {
- vertical-align: top;
- color: #f00;
-}
-
-.objectBox-sourceLink {
- position: absolute;
- right: 4px;
- top: 2px;
- padding-left: 8px;
- font-family: Lucida Grande, sans-serif;
- font-weight: bold;
- color: #0000FF;
-}
-
-/************************************************************************************************/
-/*
-//TODO: remove this when console2 is finished
-*/
-/*
-.logRow-group {
- background: #EEEEEE;
- border-bottom: none;
-}
-
-.logGroup {
- background: #EEEEEE;
-}
-
-.logGroupBox {
- margin-left: 24px;
- border-top: 1px solid #D7D7D7;
- border-left: 1px solid #D7D7D7;
-}/**/
-
-/************************************************************************************************/
-.selectorTag,.selectorId,.selectorClass {
- font-family: Monaco, monospace;
- font-weight: normal;
-}
-
-.selectorTag {
- color: #0000FF;
-}
-
-.selectorId {
- color: DarkBlue;
-}
-
-.selectorClass {
- color: red;
-}
-
-/************************************************************************************************/
-.objectBox-element {
- font-family: Monaco, monospace;
- color: #000088;
-}
-
-.nodeChildren {
- padding-left: 26px;
-}
-
-.nodeTag {
- color: blue;
- cursor: pointer;
-}
-
-.nodeValue {
- color: #FF0000;
- font-weight: normal;
-}
-
-.nodeText,.nodeComment {
- margin: 0 2px;
- vertical-align: top;
-}
-
-.nodeText {
- color: #333333;
- font-family: Monaco, monospace;
-}
-
-.nodeComment {
- color: DarkGreen;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.nodeHidden, .nodeHidden * {
- color: #888888;
-}
-
-.nodeHidden .nodeTag {
- color: #5F82D9;
-}
-
-.nodeHidden .nodeValue {
- color: #D86060;
-}
-
-.selectedElement .nodeHidden, .selectedElement .nodeHidden * {
- color: SkyBlue !important;
-}
-
-
-/************************************************************************************************/
-.log-object {
- /*
- _position: relative;
- _height: 100%;
- /**/
-}
-
-.property {
- position: relative;
- clear: both;
- height: 15px;
-}
-
-.propertyNameCell {
- vertical-align: top;
- float: left;
- width: 28%;
- position: absolute;
- left: 0;
- z-index: 0;
-}
-
-.propertyValueCell {
- float: right;
- width: 68%;
- background: #fff;
- position: absolute;
- padding-left: 5px;
- display: table-cell;
- right: 0;
- z-index: 1;
- /*
- _position: relative;
- /**/
-}
-
-.propertyName {
- font-weight: bold;
-}
-
-.FirebugPopup {
- height: 100% !important;
-}
-
-.FirebugPopup #fbWindowButtons {
- display: none !important;
-}
-
-.FirebugPopup #fbHSplitter {
- display: none !important;
-}
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.html b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.html
deleted file mode 100644
index aa078099..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.html
+++ /dev/null
@@ -1,215 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/DTD/strict.dtd">
-<html>
-<head>
-<meta http-equiv="content-type" content="text/html; charset=utf-8">
-<title>Firebug Lite</title>
-<!-- An empty script to avoid FOUC when loading the stylesheet -->
-<script type="text/javascript"></script>
-<style type="text/css" media="screen">@import "firebug.css";</style>
-<style>html,body{margin:0;padding:0;overflow:hidden;}</style>
-</head>
-<body class="fbBody">
-<table id="fbChrome" cellpadding="0" cellspacing="0" border="0">
- <tbody>
- <tr>
- <!-- Interface - Top Area -->
- <td id="fbTop" colspan="2">
-
- <!--
- <div>
- --><!-- <span id="fbToolbarErrors" class="fbErrors">2 errors</span> --><!--
- <input type="text" id="fbToolbarSearch" />
- </div>
- -->
-
- <!-- Window Buttons -->
- <div id="fbWindowButtons">
- <a id="fbWindow_btDeactivate" class="fbSmallButton fbHover" title="Deactivate Firebug for this web page">&nbsp;</a>
- <a id="fbWindow_btDetach" class="fbSmallButton fbHover" title="Open Firebug in popup window">&nbsp;</a>
- <a id="fbWindow_btClose" class="fbSmallButton fbHover" title="Minimize Firebug">&nbsp;</a>
- </div>
-
- <!-- Toolbar buttons and Status Bar -->
- <div id="fbToolbar">
- <div id="fbToolbarContent">
-
- <!-- Firebug Button -->
- <span id="fbToolbarIcon">
- <a id="fbFirebugButton" class="fbIconButton" class="fbHover" target="_blank">&nbsp;</a>
- </span>
-
- <!--
- <span id="fbLeftToolbarErrors" class="fbErrors">2 errors</span>
- -->
-
- <!-- Toolbar Buttons -->
- <span id="fbToolbarButtons">
- <!-- Fixed Toolbar Buttons -->
- <span id="fbFixedButtons">
- <a id="fbChrome_btInspect" class="fbButton fbHover" title="Click an element in the page to inspect">Inspect</a>
- </span>
-
- <!-- Console Panel Toolbar Buttons -->
- <span id="fbConsoleButtons" class="fbToolbarButtons">
- <a id="fbConsole_btClear" class="fbButton fbHover" title="Clear the console">Clear</a>
- </span>
-
- <!-- HTML Panel Toolbar Buttons -->
- <!--
- <span id="fbHTMLButtons" class="fbToolbarButtons">
- <a id="fbHTML_btEdit" class="fbHover" title="Edit this HTML">Edit</a>
- </span>
- -->
- </span>
-
- <!-- Status Bar -->
- <span id="fbStatusBarBox">
- <span class="fbToolbarSeparator"></span>
- <!-- HTML Panel Status Bar -->
- <!--
- <span id="fbHTMLStatusBar" class="fbStatusBar fbToolbarButtons">
- </span>
- -->
- </span>
-
- </div>
-
- </div>
-
- <!-- PanelBars -->
- <div id="fbPanelBarBox">
-
- <!-- Main PanelBar -->
- <div id="fbPanelBar1" class="fbPanelBar">
- <a id="fbConsoleTab" class="fbTab fbHover">
- <span class="fbTabL"></span>
- <span class="fbTabText">Console</span>
- <span class="fbTabMenuTarget"></span>
- <span class="fbTabR"></span>
- </a>
- <a id="fbHTMLTab" class="fbTab fbHover">
- <span class="fbTabL"></span>
- <span class="fbTabText">HTML</span>
- <span class="fbTabR"></span>
- </a>
- <a class="fbTab fbHover">
- <span class="fbTabL"></span>
- <span class="fbTabText">CSS</span>
- <span class="fbTabR"></span>
- </a>
- <a class="fbTab fbHover">
- <span class="fbTabL"></span>
- <span class="fbTabText">Script</span>
- <span class="fbTabR"></span>
- </a>
- <a class="fbTab fbHover">
- <span class="fbTabL"></span>
- <span class="fbTabText">DOM</span>
- <span class="fbTabR"></span>
- </a>
- </div>
-
- <!-- Side PanelBars -->
- <div id="fbPanelBar2Box" class="hide">
- <div id="fbPanelBar2" class="fbPanelBar">
- <!--
- <a class="fbTab fbHover">
- <span class="fbTabL"></span>
- <span class="fbTabText">Style</span>
- <span class="fbTabR"></span>
- </a>
- <a class="fbTab fbHover">
- <span class="fbTabL"></span>
- <span class="fbTabText">Layout</span>
- <span class="fbTabR"></span>
- </a>
- <a class="fbTab fbHover">
- <span class="fbTabL"></span>
- <span class="fbTabText">DOM</span>
- <span class="fbTabR"></span>
- </a>
- -->
- </div>
- </div>
-
- </div>
-
- <!-- Horizontal Splitter -->
- <div id="fbHSplitter">&nbsp;</div>
-
- </td>
- </tr>
-
- <!-- Interface - Main Area -->
- <tr id="fbContent">
-
- <!-- Panels -->
- <td id="fbPanelBox1">
- <div id="fbPanel1" class="fbFitHeight">
- <div id="fbConsole" class="fbPanel"></div>
- <div id="fbHTML" class="fbPanel"></div>
- </div>
- </td>
-
- <!-- Side Panel Box -->
- <td id="fbPanelBox2" class="hide">
-
- <!-- VerticalSplitter -->
- <div id="fbVSplitter" class="fbVSplitter">&nbsp;</div>
-
- <!-- Side Panels -->
- <div id="fbPanel2" class="fbFitHeight">
-
- <!-- HTML Side Panels -->
- <div id="fbHTML_Style" class="fbPanel"></div>
- <div id="fbHTML_Layout" class="fbPanel"></div>
- <div id="fbHTML_DOM" class="fbPanel"></div>
-
- </div>
-
- <!-- Large Command Line -->
- <textarea id="fbLargeCommandLine" class="fbFitHeight"></textarea>
-
- <!-- Large Command Line Buttons -->
- <div id="fbLargeCommandButtons">
- <a id="fbCommand_btRun" class="fbButton fbHover">Run</a>
- <a id="fbCommand_btClear" class="fbButton fbHover">Clear</a>
-
- <a id="fbSmallCommandLineIcon" class="fbSmallButton fbHover"></a>
- </div>
-
- </td>
-
- </tr>
-
- <!-- Interface - Bottom Area -->
- <tr id="fbBottom" class="hide">
-
- <!-- Command Line -->
- <td id="fbCommand" colspan="2">
- <div id="fbCommandBox">
- <div id="fbCommandIcon">&gt;&gt;&gt;</div>
- <input id="fbCommandLine" name="fbCommandLine" type="text" />
- <a id="fbLargeCommandLineIcon" class="fbSmallButton fbHover"></a>
- </div>
- </td>
-
- </tr>
-
- </tbody>
-</table>
-<span id="fbMiniChrome">
- <span id="fbMiniContent">
- <span id="fbMiniIcon" title="Open Firebug Lite"></span>
- <span id="fbMiniErrors" class="fbErrors"><!-- 2 errors --></span>
- </span>
-</span>
-<!--
-<div id="fbErrorPopup">
- <div id="fbErrorPopupContent">
- <div id="fbErrorIndicator" class="fbErrors">2 errors</div>
- </div>
-</div>
- -->
-</body>
-</html> \ No newline at end of file
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.png
deleted file mode 100644
index e10affeb..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/firebug.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/group.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/group.gif
deleted file mode 100644
index 8db97c21..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/group.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/html.css b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/html.css
deleted file mode 100644
index 5b7c5f4b..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/html.css
+++ /dev/null
@@ -1,272 +0,0 @@
-/* See license.txt for terms of usage */
-
-.panelNode-html {
- -moz-box-sizing: padding-box;
- padding: 4px 0 0 2px;
-}
-
-.nodeBox {
- position: relative;
- font-family: Monaco, monospace;
- padding-left: 13px;
- -moz-user-select: -moz-none;
-}
-.nodeBox.search-selection {
- -moz-user-select: text;
-}
-.twisty {
- position: absolute;
- left: 0px;
- top: 0px;
- width: 14px;
- height: 14px;
-}
-
-.nodeChildBox {
- margin-left: 12px;
- display: none;
-}
-
-.nodeLabel,
-.nodeCloseLabel {
- margin: -2px 2px 0 2px;
- border: 2px solid transparent;
- -moz-border-radius: 3px;
- padding: 0 2px;
- color: #000088;
-}
-
-.nodeCloseLabel {
- display: none;
-}
-
-.nodeTag {
- cursor: pointer;
- color: blue;
-}
-
-.nodeValue {
- color: #FF0000;
- font-weight: normal;
-}
-
-.nodeText,
-.nodeComment {
- margin: 0 2px;
- vertical-align: top;
-}
-
-.nodeText {
- color: #333333;
-}
-
-.nodeWhiteSpace {
- border: 1px solid LightGray;
- white-space: pre; /* otherwise the border will be collapsed around zero pixels */
- margin-left: 1px;
- color: gray;
-}
-
-
-.nodeWhiteSpace_Space {
- border: 1px solid #ddd;
-}
-
-.nodeTextEntity {
- border: 1px solid gray;
- white-space: pre; /* otherwise the border will be collapsed around zero pixels */
- margin-left: 1px;
-}
-
-.nodeComment {
- color: DarkGreen;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.nodeBox.highlightOpen > .nodeLabel {
- background-color: #EEEEEE;
-}
-
-.nodeBox.highlightOpen > .nodeCloseLabel,
-.nodeBox.highlightOpen > .nodeChildBox,
-.nodeBox.open > .nodeCloseLabel,
-.nodeBox.open > .nodeChildBox {
- display: block;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.nodeBox.selected > .nodeLabel > .nodeLabelBox,
-.nodeBox.selected > .nodeLabel {
- border-color: Highlight;
- background-color: Highlight;
- color: HighlightText !important;
-}
-
-.nodeBox.selected > .nodeLabel > .nodeLabelBox,
-.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
-.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
-.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText {
- color: inherit !important;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.nodeBox.highlighted > .nodeLabel {
- border-color: Highlight !important;
- background-color: cyan !important;
- color: #000000 !important;
-}
-
-.nodeBox.highlighted > .nodeLabel > .nodeLabelBox,
-.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeTag,
-.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
-.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeText {
- color: #000000 !important;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox,
-.nodeBox.nodeHidden .nodeCloseLabel,
-.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeText,
-.nodeBox.nodeHidden .nodeText {
- color: #888888;
-}
-
-.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeTag,
-.nodeBox.nodeHidden .nodeCloseLabel > .nodeCloseLabelBox > .nodeTag {
- color: #5F82D9;
-}
-
-.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue {
- color: #D86060;
-}
-
-.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox,
-.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
-.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
-.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeText {
- color: SkyBlue !important;
-}
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-.nodeBox.mutated > .nodeLabel,
-.nodeAttr.mutated,
-.nodeValue.mutated,
-.nodeText.mutated,
-.nodeBox.mutated > .nodeText {
- background-color: #EFFF79;
- color: #FF0000 !important;
-}
-
-.nodeBox.selected.mutated > .nodeLabel,
-.nodeBox.selected.mutated > .nodeLabel > .nodeLabelBox,
-.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr.mutated > .nodeValue,
-.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue.mutated,
-.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText.mutated {
- background-color: #EFFF79;
- border-color: #EFFF79;
- color: #FF0000 !important;
-}
-
-/************************************************************************************************/
-
-.logRow-dirxml {
- padding-left: 0;
-}
-
-.soloElement > .nodeBox {
- padding-left: 0;
-}
-
-.useA11y .nodeLabel.focused {
- outline: 2px solid #FF9933;
- -moz-outline-radius: 3px;
- outline-offset: -2px;
-}
-
-.useA11y .nodeLabelBox:focus {
- outline: none;
-}
-
-/************************************************************************************************/
-
-.breakpointCode .twisty {
- display: none;
-}
-
-.breakpointCode .nodeBox.containerNodeBox,
-.breakpointCode .nodeLabel {
- padding-left: 0px;
- margin-left: 0px;
- font-family: Monaco, monospace !important;
-}
-
-.breakpointCode .nodeTag,
-.breakpointCode .nodeAttr,
-.breakpointCode .nodeText,
-.breakpointCode .nodeValue,
-.breakpointCode .nodeLabel {
- color: DarkGreen !important;
-}
-
-.breakpointMutationType {
- position: absolute;
- top: 4px;
- right: 20px;
- color: gray;
-}
-
-
-
-
-
-
-/************************************************************************************************/
-/************************************************************************************************/
-/************************************************************************************************/
-/************************************************************************************************/
-/************************************************************************************************/
-/************************************************************************************************/
-/************************************************************************************************/
-/************************************************************************************************/
-/************************************************************************************************/
-/************************************************************************************************/
-
-
-
-/************************************************************************************************/
-/* Twisties */
-
-.twisty,
-.logRow-errorMessage > .hasTwisty > .errorTitle,
-.logRow-log > .objectBox-array.hasTwisty,
-.logRow-spy .spyHead .spyTitle,
-.logGroup > .logRow,
-.memberRow.hasChildren > .memberLabelCell > .memberLabel,
-.hasHeaders .netHrefLabel,
-.netPageRow > .netCol > .netPageTitle {
- background-image: url(twistyClosed.png);
- background-repeat: no-repeat;
- background-position: 2px 2px;
- min-height: 12px;
-}
-
-.logRow-errorMessage > .hasTwisty.opened > .errorTitle,
-.logRow-log > .objectBox-array.hasTwisty.opened,
-.logRow-spy.opened .spyHead .spyTitle,
-.logGroup.opened > .logRow,
-.memberRow.hasChildren.opened > .memberLabelCell > .memberLabel,
-.nodeBox.highlightOpen > .nodeLabel > .twisty,
-.nodeBox.open > .nodeLabel > .twisty,
-.netRow.opened > .netCol > .netHrefLabel,
-.netPageRow.opened > .netCol > .netPageTitle {
- background-image: url(twistyOpen.png);
-}
-
-.twisty {
- background-position: 4px 4px;
-} \ No newline at end of file
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/infoIcon.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/infoIcon.gif
deleted file mode 100644
index 0618e208..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/infoIcon.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/infoIcon.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/infoIcon.png
deleted file mode 100644
index da1e5334..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/infoIcon.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/loading_16.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/loading_16.gif
deleted file mode 100644
index 085ccaec..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/loading_16.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/min.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/min.png
deleted file mode 100644
index 1034d66f..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/min.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/minHover.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/minHover.png
deleted file mode 100644
index b0d1e1af..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/minHover.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/off.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/off.png
deleted file mode 100644
index b70b1d24..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/off.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/offHover.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/offHover.png
deleted file mode 100644
index f3670f19..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/offHover.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/pixel_transparent.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/pixel_transparent.gif
deleted file mode 100644
index 6865c960..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/pixel_transparent.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/roundCorner.svg b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/roundCorner.svg
deleted file mode 100644
index 2dfa7280..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/roundCorner.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg xmlns="http://www.w3.org/2000/svg">
- <rect fill="white" x="0" y="0" width="100%" height="100%" />
- <rect fill="highlight" x="0" y="0" width="100%" height="100%" rx="2px"/>
-</svg>
-
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/search.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/search.gif
deleted file mode 100644
index 2a620987..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/search.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/search.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/search.png
deleted file mode 100644
index fba33b8a..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/search.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/shadow.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/shadow.gif
deleted file mode 100644
index af7f537e..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/shadow.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/shadow2.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/shadow2.gif
deleted file mode 100644
index 099cbf35..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/shadow2.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/shadowAlpha.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/shadowAlpha.png
deleted file mode 100644
index a2561df9..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/shadowAlpha.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/sprite.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/sprite.png
deleted file mode 100644
index 33d2c4d4..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/sprite.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabHoverLeft.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabHoverLeft.png
deleted file mode 100644
index 0fb24d0c..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabHoverLeft.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabHoverMid.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabHoverMid.png
deleted file mode 100644
index fbccab54..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabHoverMid.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabHoverRight.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabHoverRight.png
deleted file mode 100644
index 3db0f361..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabHoverRight.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabLeft.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabLeft.png
deleted file mode 100644
index a6cc9e94..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabLeft.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuCheckbox.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuCheckbox.png
deleted file mode 100644
index 4726e622..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuCheckbox.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuPin.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuPin.png
deleted file mode 100644
index eb4b11ef..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuPin.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuRadio.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuRadio.png
deleted file mode 100644
index 55b982d7..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuRadio.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuTarget.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuTarget.png
deleted file mode 100644
index 957bd9f2..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuTarget.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuTargetHover.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuTargetHover.png
deleted file mode 100644
index 200a3708..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMenuTargetHover.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMid.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMid.png
deleted file mode 100644
index 68986c3b..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabMid.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabRight.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabRight.png
deleted file mode 100644
index 50113079..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tabRight.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorBorders.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorBorders.gif
deleted file mode 100644
index 0ee54978..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorBorders.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorBorders.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorBorders.png
deleted file mode 100644
index 21682c3d..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorBorders.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorCorners.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorCorners.gif
deleted file mode 100644
index 04f84215..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorCorners.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorCorners.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorCorners.png
deleted file mode 100644
index a0f839dc..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/textEditorCorners.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/titlebarMid.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/titlebarMid.png
deleted file mode 100644
index 10998ae7..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/titlebarMid.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/toolbarMid.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/toolbarMid.png
deleted file mode 100644
index aa21dee6..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/toolbarMid.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tree_close.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tree_close.gif
deleted file mode 100644
index e26728ab..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tree_close.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tree_open.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tree_open.gif
deleted file mode 100644
index edf662f3..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/tree_open.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/twistyClosed.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/twistyClosed.png
deleted file mode 100644
index f80319b0..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/twistyClosed.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/twistyOpen.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/twistyOpen.png
deleted file mode 100644
index 86801243..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/twistyOpen.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/up.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/up.png
deleted file mode 100644
index 2174d03a..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/up.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/upActive.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/upActive.png
deleted file mode 100644
index 236cf676..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/upActive.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/upHover.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/upHover.png
deleted file mode 100644
index cd813170..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/upHover.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/warningIcon.gif b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/warningIcon.gif
deleted file mode 100644
index 84972788..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/warningIcon.gif
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/warningIcon.png b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/warningIcon.png
deleted file mode 100644
index de51084e..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/skin/xp/warningIcon.png
+++ /dev/null
Binary files differ
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/src/firebug-lite-debug.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/src/firebug-lite-debug.js
deleted file mode 100644
index 40b1ae70..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/firebug-lite/src/firebug-lite-debug.js
+++ /dev/null
@@ -1,31176 +0,0 @@
-(function(){
-
-/*!*************************************************************
- *
- * Firebug Lite 1.4.0
- *
- * Copyright (c) 2007, Parakey Inc.
- * Released under BSD license.
- * More information: http://getfirebug.com/firebuglite
- *
- **************************************************************/
-
-/*!
- * CSS selectors powered by:
- *
- * Sizzle CSS Selector Engine - v1.0
- * Copyright 2009, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
- * More information: http://sizzlejs.com/
- */
-
-/** @namespace describe lib */
-
-// FIXME: xxxpedro if we use "var FBL = {}" the FBL won't appear in the DOM Panel in IE
-var FBL = {};
-
-( /** @scope s_lib @this FBL */ function() {
-// ************************************************************************************************
-
-// ************************************************************************************************
-// Constants
-
-var productionDir = "http://getfirebug.com/releases/lite/";
-var bookmarkletVersion = 4;
-
-// ************************************************************************************************
-
-var reNotWhitespace = /[^\s]/;
-var reSplitFile = /:\/{1,3}(.*?)\/([^\/]*?)\/?($|\?.*)/;
-
-// Globals
-this.reJavascript = /\s*javascript:\s*(.*)/;
-this.reChrome = /chrome:\/\/([^\/]*)\//;
-this.reFile = /file:\/\/([^\/]*)\//;
-
-
-// ************************************************************************************************
-// properties
-
-var userAgent = navigator.userAgent.toLowerCase();
-this.isFirefox = /firefox/.test(userAgent);
-this.isOpera = /opera/.test(userAgent);
-this.isSafari = /webkit/.test(userAgent);
-this.isIE = /msie/.test(userAgent) && !/opera/.test(userAgent);
-this.isIE6 = /msie 6/i.test(navigator.appVersion);
-this.browserVersion = (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1];
-this.isIElt8 = this.isIE && (this.browserVersion-0 < 8);
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-this.NS = null;
-this.pixelsPerInch = null;
-
-
-// ************************************************************************************************
-// Namespaces
-
-var namespaces = [];
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-this.ns = function(fn)
-{
- var ns = {};
- namespaces.push(fn, ns);
- return ns;
-};
-
-var FBTrace = null;
-
-this.initialize = function()
-{
- // Firebug Lite is already running in persistent mode so we just quit
- if (window.firebug && firebug.firebuglite || window.console && console.firebuglite)
- return;
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // initialize environment
-
- // point the FBTrace object to the local variable
- if (FBL.FBTrace)
- FBTrace = FBL.FBTrace;
- else
- FBTrace = FBL.FBTrace = {};
-
- // check if the actual window is a persisted chrome context
- var isChromeContext = window.Firebug && typeof window.Firebug.SharedEnv == "object";
-
- // chrome context of the persistent application
- if (isChromeContext)
- {
- // TODO: xxxpedro persist - make a better synchronization
- sharedEnv = window.Firebug.SharedEnv;
- delete window.Firebug.SharedEnv;
-
- FBL.Env = sharedEnv;
- FBL.Env.isChromeContext = true;
- FBTrace.messageQueue = FBL.Env.traceMessageQueue;
- }
- // non-persistent application
- else
- {
- FBL.NS = document.documentElement.namespaceURI;
- FBL.Env.browser = window;
- FBL.Env.destroy = destroyEnvironment;
-
- if (document.documentElement.getAttribute("debug") == "true")
- FBL.Env.Options.startOpened = true;
-
- // find the URL location of the loaded application
- findLocation();
-
- // TODO: get preferences here...
- // The problem is that we don't have the Firebug object yet, so we can't use
- // Firebug.loadPrefs. We're using the Store module directly instead.
- var prefs = FBL.Store.get("FirebugLite") || {};
- FBL.Env.DefaultOptions = FBL.Env.Options;
- FBL.Env.Options = FBL.extend(FBL.Env.Options, prefs.options || {});
-
- if (FBL.isFirefox &&
- typeof FBL.Env.browser.console == "object" &&
- FBL.Env.browser.console.firebug &&
- FBL.Env.Options.disableWhenFirebugActive)
- return;
- }
-
- // exposes the FBL to the global namespace when in debug mode
- if (FBL.Env.isDebugMode)
- {
- FBL.Env.browser.FBL = FBL;
- }
-
- // check browser compatibilities
- this.isQuiksMode = FBL.Env.browser.document.compatMode == "BackCompat";
- this.isIEQuiksMode = this.isIE && this.isQuiksMode;
- this.isIEStantandMode = this.isIE && !this.isQuiksMode;
-
- this.noFixedPosition = this.isIE6 || this.isIEQuiksMode;
-
- // after creating/synchronizing the environment, initialize the FBTrace module
- if (FBL.Env.Options.enableTrace) FBTrace.initialize();
-
- if (FBTrace.DBG_INITIALIZE && isChromeContext) FBTrace.sysout("FBL.initialize - persistent application", "initialize chrome context");
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // initialize namespaces
-
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FBL.initialize", namespaces.length/2+" namespaces BEGIN");
-
- for (var i = 0; i < namespaces.length; i += 2)
- {
- var fn = namespaces[i];
- var ns = namespaces[i+1];
- fn.apply(ns);
- }
-
- if (FBTrace.DBG_INITIALIZE) {
- FBTrace.sysout("FBL.initialize", namespaces.length/2+" namespaces END");
- FBTrace.sysout("FBL waitForDocument", "waiting document load");
- }
-
- FBL.Ajax.initialize();
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // finish environment initialization
- FBL.Firebug.loadPrefs();
-
- if (FBL.Env.Options.enablePersistent)
- {
- // TODO: xxxpedro persist - make a better synchronization
- if (isChromeContext)
- {
- FBL.FirebugChrome.clone(FBL.Env.FirebugChrome);
- }
- else
- {
- FBL.Env.FirebugChrome = FBL.FirebugChrome;
- FBL.Env.traceMessageQueue = FBTrace.messageQueue;
- }
- }
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // wait document load
-
- waitForDocument();
-};
-
-var waitForDocument = function waitForDocument()
-{
- // document.body not available in XML+XSL documents in Firefox
- var doc = FBL.Env.browser.document;
- var body = doc.getElementsByTagName("body")[0];
-
- if (body)
- {
- calculatePixelsPerInch(doc, body);
- onDocumentLoad();
- }
- else
- setTimeout(waitForDocument, 50);
-};
-
-var onDocumentLoad = function onDocumentLoad()
-{
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FBL onDocumentLoad", "document loaded");
-
- // fix IE6 problem with cache of background images, causing a lot of flickering
- if (FBL.isIE6)
- fixIE6BackgroundImageCache();
-
- // chrome context of the persistent application
- if (FBL.Env.Options.enablePersistent && FBL.Env.isChromeContext)
- {
- // finally, start the application in the chrome context
- FBL.Firebug.initialize();
-
- // if is not development mode, remove the shared environment cache object
- // used to synchronize the both persistent contexts
- if (!FBL.Env.isDevelopmentMode)
- {
- sharedEnv.destroy();
- sharedEnv = null;
- }
- }
- // non-persistent application
- else
- {
- FBL.FirebugChrome.create();
- }
-};
-
-// ************************************************************************************************
-// Env
-
-var sharedEnv;
-
-this.Env =
-{
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Env Options (will be transported to Firebug options)
- Options:
- {
- saveCookies: true,
-
- saveWindowPosition: false,
- saveCommandLineHistory: false,
-
- startOpened: false,
- startInNewWindow: false,
- showIconWhenHidden: true,
-
- overrideConsole: true,
- ignoreFirebugElements: true,
- disableWhenFirebugActive: true,
-
- disableXHRListener: false,
- disableResourceFetching: false,
-
- enableTrace: false,
- enablePersistent: false
-
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Library location
- Location:
- {
- sourceDir: null,
- baseDir: null,
- skinDir: null,
- skin: null,
- app: null
- },
-
- skin: "xp",
- useLocalSkin: false,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Env states
- isDevelopmentMode: false,
- isDebugMode: false,
- isChromeContext: false,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Env references
- browser: null,
- chrome: null
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var destroyEnvironment = function destroyEnvironment()
-{
- setTimeout(function()
- {
- FBL = null;
- }, 100);
-};
-
-// ************************************************************************************************
-// Library location
-
-var findLocation = function findLocation()
-{
- var reFirebugFile = /(firebug-lite(?:-\w+)?(?:\.js|\.jgz))(?:#(.+))?$/;
- var reGetFirebugSite = /(?:http|https):\/\/getfirebug.com\//;
- var isGetFirebugSite;
-
- var rePath = /^(.*\/)/;
- var reProtocol = /^\w+:\/\//;
- var path = null;
- var doc = document;
-
- // Firebug Lite 1.3.0 bookmarklet identification
- var script = doc.getElementById("FirebugLite");
-
- var scriptSrc;
- var hasSrcAttribute = true;
-
- // If the script was loaded via bookmarklet, we already have the script tag
- if (script)
- {
- scriptSrc = script.src;
- file = reFirebugFile.exec(scriptSrc);
-
- var version = script.getAttribute("FirebugLite");
- var number = version ? parseInt(version) : 0;
-
- if (!version || !number || number < bookmarkletVersion)
- {
- FBL.Env.bookmarkletOutdated = true;
- }
- }
- // otherwise we must search for the correct script tag
- else
- {
- for(var i=0, s=doc.getElementsByTagName("script"), si; si=s[i]; i++)
- {
- var file = null;
- if ( si.nodeName.toLowerCase() == "script" )
- {
- if (file = reFirebugFile.exec(si.getAttribute("firebugSrc")))
- {
- scriptSrc = si.getAttribute("firebugSrc");
- hasSrcAttribute = false;
- }
- else if (file = reFirebugFile.exec(si.src))
- {
- scriptSrc = si.src;
- }
- else
- continue;
-
- script = si;
- break;
- }
- }
- }
-
- // mark the script tag to be ignored by Firebug Lite
- if (script)
- script.firebugIgnore = true;
-
- if (file)
- {
- var fileName = file[1];
- var fileOptions = file[2];
-
- // absolute path
- if (reProtocol.test(scriptSrc)) {
- path = rePath.exec(scriptSrc)[1];
-
- }
- // relative path
- else
- {
- var r = rePath.exec(scriptSrc);
- var src = r ? r[1] : scriptSrc;
- var backDir = /^((?:\.\.\/)+)(.*)/.exec(src);
- var reLastDir = /^(.*\/)[^\/]+\/$/;
- path = rePath.exec(location.href)[1];
-
- // "../some/path"
- if (backDir)
- {
- var j = backDir[1].length/3;
- var p;
- while (j-- > 0)
- path = reLastDir.exec(path)[1];
-
- path += backDir[2];
- }
-
- else if(src.indexOf("/") != -1)
- {
- // "./some/path"
- if(/^\.\/./.test(src))
- {
- path += src.substring(2);
- }
- // "/some/path"
- else if(/^\/./.test(src))
- {
- var domain = /^(\w+:\/\/[^\/]+)/.exec(path);
- path = domain[1] + src;
- }
- // "some/path"
- else
- {
- path += src;
- }
- }
- }
- }
-
- FBL.Env.isChromeExtension = script && script.getAttribute("extension") == "Chrome";
- if (FBL.Env.isChromeExtension)
- {
- path = productionDir;
- FBL.Env.bookmarkletOutdated = false;
- script = {innerHTML: "{showIconWhenHidden:false}"};
- }
-
- isGetFirebugSite = reGetFirebugSite.test(path);
-
- if (isGetFirebugSite && path.indexOf("/releases/lite/") == -1)
- {
- // See Issue 4587 - If we are loading the script from getfirebug.com shortcut, like
- // https://getfirebug.com/firebug-lite.js, then we must manually add the full path,
- // otherwise the Env.Location will hold the wrong path, which will in turn lead to
- // undesirable effects like the problem in Issue 4587
- path += "releases/lite/" + (fileName == "firebug-lite-beta.js" ? "beta/" : "latest/");
- }
-
- var m = path && path.match(/([^\/]+)\/$/) || null;
-
- if (path && m)
- {
- var Env = FBL.Env;
-
- // Always use the local skin when running in the same domain
- // See Issue 3554: Firebug Lite should use local images when loaded locally
- Env.useLocalSkin = path.indexOf(location.protocol + "//" + location.host + "/") == 0 &&
- // but we cannot use the locan skin when loaded from getfirebug.com, otherwise
- // the bookmarklet won't work when visiting getfirebug.com
- !isGetFirebugSite;
-
- // detecting development and debug modes via file name
- if (fileName == "firebug-lite-dev.js")
- {
- Env.isDevelopmentMode = true;
- Env.isDebugMode = true;
- }
- else if (fileName == "firebug-lite-debug.js")
- {
- Env.isDebugMode = true;
- }
-
- // process the <html debug="true">
- if (Env.browser.document.documentElement.getAttribute("debug") == "true")
- {
- Env.Options.startOpened = true;
- }
-
- // process the Script URL Options
- if (fileOptions)
- {
- var options = fileOptions.split(",");
-
- for (var i = 0, length = options.length; i < length; i++)
- {
- var option = options[i];
- var name, value;
-
- if (option.indexOf("=") != -1)
- {
- var parts = option.split("=");
- name = parts[0];
- value = eval(unescape(parts[1]));
- }
- else
- {
- name = option;
- value = true;
- }
-
- if (name == "debug")
- {
- Env.isDebugMode = !!value;
- }
- else if (name in Env.Options)
- {
- Env.Options[name] = value;
- }
- else
- {
- Env[name] = value;
- }
- }
- }
-
- // process the Script JSON Options
- if (hasSrcAttribute)
- {
- var innerOptions = FBL.trim(script.innerHTML);
- if (innerOptions)
- {
- var innerOptionsObject = eval("(" + innerOptions + ")");
-
- for (var name in innerOptionsObject)
- {
- var value = innerOptionsObject[name];
-
- if (name == "debug")
- {
- Env.isDebugMode = !!value;
- }
- else if (name in Env.Options)
- {
- Env.Options[name] = value;
- }
- else
- {
- Env[name] = value;
- }
- }
- }
- }
-
- if (!Env.Options.saveCookies)
- FBL.Store.remove("FirebugLite");
-
- // process the Debug Mode
- if (Env.isDebugMode)
- {
- Env.Options.startOpened = true;
- Env.Options.enableTrace = true;
- Env.Options.disableWhenFirebugActive = false;
- }
-
- var loc = Env.Location;
- var isProductionRelease = path.indexOf(productionDir) != -1;
-
- loc.sourceDir = path;
- loc.baseDir = path.substr(0, path.length - m[1].length - 1);
- loc.skinDir = (isProductionRelease ? path : loc.baseDir) + "skin/" + Env.skin + "/";
- loc.skin = loc.skinDir + "firebug.html";
- loc.app = path + fileName;
- }
- else
- {
- throw new Error("Firebug Error: Library path not found");
- }
-};
-
-// ************************************************************************************************
-// Basics
-
-this.bind = function() // fn, thisObject, args => thisObject.fn(args, arguments);
-{
- var args = cloneArray(arguments), fn = args.shift(), object = args.shift();
- return function() { return fn.apply(object, arrayInsert(cloneArray(args), 0, arguments)); };
-};
-
-this.bindFixed = function() // fn, thisObject, args => thisObject.fn(args);
-{
- var args = cloneArray(arguments), fn = args.shift(), object = args.shift();
- return function() { return fn.apply(object, args); };
-};
-
-this.extend = function(l, r)
-{
- var newOb = {};
- for (var n in l)
- newOb[n] = l[n];
- for (var n in r)
- newOb[n] = r[n];
- return newOb;
-};
-
-this.descend = function(prototypeParent, childProperties)
-{
- function protoSetter() {};
- protoSetter.prototype = prototypeParent;
- var newOb = new protoSetter();
- for (var n in childProperties)
- newOb[n] = childProperties[n];
- return newOb;
-};
-
-this.append = function(l, r)
-{
- for (var n in r)
- l[n] = r[n];
-
- return l;
-};
-
-this.keys = function(map) // At least sometimes the keys will be on user-level window objects
-{
- var keys = [];
- try
- {
- for (var name in map) // enumeration is safe
- keys.push(name); // name is string, safe
- }
- catch (exc)
- {
- // Sometimes we get exceptions trying to iterate properties
- }
-
- return keys; // return is safe
-};
-
-this.values = function(map)
-{
- var values = [];
- try
- {
- for (var name in map)
- {
- try
- {
- values.push(map[name]);
- }
- catch (exc)
- {
- // Sometimes we get exceptions trying to access properties
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("lib.values FAILED ", exc);
- }
-
- }
- }
- catch (exc)
- {
- // Sometimes we get exceptions trying to iterate properties
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("lib.values FAILED ", exc);
- }
-
- return values;
-};
-
-this.remove = function(list, item)
-{
- for (var i = 0; i < list.length; ++i)
- {
- if (list[i] == item)
- {
- list.splice(i, 1);
- break;
- }
- }
-};
-
-this.sliceArray = function(array, index)
-{
- var slice = [];
- for (var i = index; i < array.length; ++i)
- slice.push(array[i]);
-
- return slice;
-};
-
-function cloneArray(array, fn)
-{
- var newArray = [];
-
- if (fn)
- for (var i = 0; i < array.length; ++i)
- newArray.push(fn(array[i]));
- else
- for (var i = 0; i < array.length; ++i)
- newArray.push(array[i]);
-
- return newArray;
-}
-
-function extendArray(array, array2)
-{
- var newArray = [];
- newArray.push.apply(newArray, array);
- newArray.push.apply(newArray, array2);
- return newArray;
-}
-
-this.extendArray = extendArray;
-this.cloneArray = cloneArray;
-
-function arrayInsert(array, index, other)
-{
- for (var i = 0; i < other.length; ++i)
- array.splice(i+index, 0, other[i]);
-
- return array;
-}
-
-// ************************************************************************************************
-
-this.createStyleSheet = function(doc, url)
-{
- //TODO: xxxpedro
- //var style = doc.createElementNS("http://www.w3.org/1999/xhtml", "style");
- var style = this.createElement("link");
- style.setAttribute("charset","utf-8");
- style.firebugIgnore = true;
- style.setAttribute("rel", "stylesheet");
- style.setAttribute("type", "text/css");
- style.setAttribute("href", url);
-
- //TODO: xxxpedro
- //style.innerHTML = this.getResource(url);
- return style;
-};
-
-this.addStyleSheet = function(doc, style)
-{
- var heads = doc.getElementsByTagName("head");
- if (heads.length)
- heads[0].appendChild(style);
- else
- doc.documentElement.appendChild(style);
-};
-
-this.appendStylesheet = function(doc, uri)
-{
- // Make sure the stylesheet is not appended twice.
- if (this.$(uri, doc))
- return;
-
- var styleSheet = this.createStyleSheet(doc, uri);
- styleSheet.setAttribute("id", uri);
- this.addStyleSheet(doc, styleSheet);
-};
-
-this.addScript = function(doc, id, src)
-{
- var element = doc.createElementNS("http://www.w3.org/1999/xhtml", "html:script");
- element.setAttribute("type", "text/javascript");
- element.setAttribute("id", id);
- if (!FBTrace.DBG_CONSOLE)
- FBL.unwrapObject(element).firebugIgnore = true;
-
- element.innerHTML = src;
- if (doc.documentElement)
- doc.documentElement.appendChild(element);
- else
- {
- // See issue 1079, the svg test case gives this error
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("lib.addScript doc has no documentElement:", doc);
- }
- return element;
-};
-
-
-// ************************************************************************************************
-
-this.getStyle = this.isIE ?
- function(el, name)
- {
- return el.currentStyle[name] || el.style[name] || undefined;
- }
- :
- function(el, name)
- {
- return el.ownerDocument.defaultView.getComputedStyle(el,null)[name]
- || el.style[name] || undefined;
- };
-
-
-// ************************************************************************************************
-// Whitespace and Entity conversions
-
-var entityConversionLists = this.entityConversionLists = {
- normal : {
- whitespace : {
- '\t' : '\u200c\u2192',
- '\n' : '\u200c\u00b6',
- '\r' : '\u200c\u00ac',
- ' ' : '\u200c\u00b7'
- }
- },
- reverse : {
- whitespace : {
- '&Tab;' : '\t',
- '&NewLine;' : '\n',
- '\u200c\u2192' : '\t',
- '\u200c\u00b6' : '\n',
- '\u200c\u00ac' : '\r',
- '\u200c\u00b7' : ' '
- }
- }
-};
-
-var normal = entityConversionLists.normal,
- reverse = entityConversionLists.reverse;
-
-function addEntityMapToList(ccode, entity)
-{
- var lists = Array.prototype.slice.call(arguments, 2),
- len = lists.length,
- ch = String.fromCharCode(ccode);
- for (var i = 0; i < len; i++)
- {
- var list = lists[i];
- normal[list]=normal[list] || {};
- normal[list][ch] = '&' + entity + ';';
- reverse[list]=reverse[list] || {};
- reverse[list]['&' + entity + ';'] = ch;
- }
-};
-
-var e = addEntityMapToList,
- white = 'whitespace',
- text = 'text',
- attr = 'attributes',
- css = 'css',
- editor = 'editor';
-
-e(0x0022, 'quot', attr, css);
-e(0x0026, 'amp', attr, text, css);
-e(0x0027, 'apos', css);
-e(0x003c, 'lt', attr, text, css);
-e(0x003e, 'gt', attr, text, css);
-e(0xa9, 'copy', text, editor);
-e(0xae, 'reg', text, editor);
-e(0x2122, 'trade', text, editor);
-
-// See http://en.wikipedia.org/wiki/Dash
-e(0x2012, '#8210', attr, text, editor); // figure dash
-e(0x2013, 'ndash', attr, text, editor); // en dash
-e(0x2014, 'mdash', attr, text, editor); // em dash
-e(0x2015, '#8213', attr, text, editor); // horizontal bar
-
-e(0x00a0, 'nbsp', attr, text, white, editor);
-e(0x2002, 'ensp', attr, text, white, editor);
-e(0x2003, 'emsp', attr, text, white, editor);
-e(0x2009, 'thinsp', attr, text, white, editor);
-e(0x200c, 'zwnj', attr, text, white, editor);
-e(0x200d, 'zwj', attr, text, white, editor);
-e(0x200e, 'lrm', attr, text, white, editor);
-e(0x200f, 'rlm', attr, text, white, editor);
-e(0x200b, '#8203', attr, text, white, editor); // zero-width space (ZWSP)
-
-//************************************************************************************************
-// Entity escaping
-
-var entityConversionRegexes = {
- normal : {},
- reverse : {}
- };
-
-var escapeEntitiesRegEx = {
- normal : function(list)
- {
- var chars = [];
- for ( var ch in list)
- {
- chars.push(ch);
- }
- return new RegExp('([' + chars.join('') + '])', 'gm');
- },
- reverse : function(list)
- {
- var chars = [];
- for ( var ch in list)
- {
- chars.push(ch);
- }
- return new RegExp('(' + chars.join('|') + ')', 'gm');
- }
-};
-
-function getEscapeRegexp(direction, lists)
-{
- var name = '', re;
- var groups = [].concat(lists);
- for (i = 0; i < groups.length; i++)
- {
- name += groups[i].group;
- }
- re = entityConversionRegexes[direction][name];
- if (!re)
- {
- var list = {};
- if (groups.length > 1)
- {
- for ( var i = 0; i < groups.length; i++)
- {
- var aList = entityConversionLists[direction][groups[i].group];
- for ( var item in aList)
- list[item] = aList[item];
- }
- } else if (groups.length==1)
- {
- list = entityConversionLists[direction][groups[0].group]; // faster for special case
- } else {
- list = {}; // perhaps should print out an error here?
- }
- re = entityConversionRegexes[direction][name] = escapeEntitiesRegEx[direction](list);
- }
- return re;
-};
-
-function createSimpleEscape(name, direction)
-{
- return function(value)
- {
- var list = entityConversionLists[direction][name];
- return String(value).replace(
- getEscapeRegexp(direction, {
- group : name,
- list : list
- }),
- function(ch)
- {
- return list[ch];
- }
- );
- };
-};
-
-function escapeGroupsForEntities(str, lists)
-{
- lists = [].concat(lists);
- var re = getEscapeRegexp('normal', lists),
- split = String(str).split(re),
- len = split.length,
- results = [],
- cur, r, i, ri = 0, l, list, last = '';
- if (!len)
- return [ {
- str : String(str),
- group : '',
- name : ''
- } ];
- for (i = 0; i < len; i++)
- {
- cur = split[i];
- if (cur == '')
- continue;
- for (l = 0; l < lists.length; l++)
- {
- list = lists[l];
- r = entityConversionLists.normal[list.group][cur];
- // if (cur == ' ' && list.group == 'whitespace' && last == ' ') // only show for runs of more than one space
- // r = ' ';
- if (r)
- {
- results[ri] = {
- 'str' : r,
- 'class' : list['class'],
- 'extra' : list.extra[cur] ? list['class']
- + list.extra[cur] : ''
- };
- break;
- }
- }
- // last=cur;
- if (!r)
- results[ri] = {
- 'str' : cur,
- 'class' : '',
- 'extra' : ''
- };
- ri++;
- }
- return results;
-};
-
-this.escapeGroupsForEntities = escapeGroupsForEntities;
-
-
-function unescapeEntities(str, lists)
-{
- var re = getEscapeRegexp('reverse', lists),
- split = String(str).split(re),
- len = split.length,
- results = [],
- cur, r, i, ri = 0, l, list;
- if (!len)
- return str;
- lists = [].concat(lists);
- for (i = 0; i < len; i++)
- {
- cur = split[i];
- if (cur == '')
- continue;
- for (l = 0; l < lists.length; l++)
- {
- list = lists[l];
- r = entityConversionLists.reverse[list.group][cur];
- if (r)
- {
- results[ri] = r;
- break;
- }
- }
- if (!r)
- results[ri] = cur;
- ri++;
- }
- return results.join('') || '';
-};
-
-
-// ************************************************************************************************
-// String escaping
-
-var escapeForTextNode = this.escapeForTextNode = createSimpleEscape('text', 'normal');
-var escapeForHtmlEditor = this.escapeForHtmlEditor = createSimpleEscape('editor', 'normal');
-var escapeForElementAttribute = this.escapeForElementAttribute = createSimpleEscape('attributes', 'normal');
-var escapeForCss = this.escapeForCss = createSimpleEscape('css', 'normal');
-
-// deprecated compatibility functions
-//this.deprecateEscapeHTML = createSimpleEscape('text', 'normal');
-//this.deprecatedUnescapeHTML = createSimpleEscape('text', 'reverse');
-//this.escapeHTML = deprecated("use appropriate escapeFor... function", this.deprecateEscapeHTML);
-//this.unescapeHTML = deprecated("use appropriate unescapeFor... function", this.deprecatedUnescapeHTML);
-
-var escapeForSourceLine = this.escapeForSourceLine = createSimpleEscape('text', 'normal');
-
-var unescapeWhitespace = createSimpleEscape('whitespace', 'reverse');
-
-this.unescapeForTextNode = function(str)
-{
- if (Firebug.showTextNodesWithWhitespace)
- str = unescapeWhitespace(str);
- if (!Firebug.showTextNodesWithEntities)
- str = escapeForElementAttribute(str);
- return str;
-};
-
-this.escapeNewLines = function(value)
-{
- return value.replace(/\r/g, "\\r").replace(/\n/g, "\\n");
-};
-
-this.stripNewLines = function(value)
-{
- return typeof(value) == "string" ? value.replace(/[\r\n]/g, " ") : value;
-};
-
-this.escapeJS = function(value)
-{
- return value.replace(/\r/g, "\\r").replace(/\n/g, "\\n").replace('"', '\\"', "g");
-};
-
-function escapeHTMLAttribute(value)
-{
- function replaceChars(ch)
- {
- switch (ch)
- {
- case "&":
- return "&amp;";
- case "'":
- return apos;
- case '"':
- return quot;
- }
- return "?";
- };
- var apos = "&#39;", quot = "&quot;", around = '"';
- if( value.indexOf('"') == -1 ) {
- quot = '"';
- apos = "'";
- } else if( value.indexOf("'") == -1 ) {
- quot = '"';
- around = "'";
- }
- return around + (String(value).replace(/[&'"]/g, replaceChars)) + around;
-}
-
-
-function escapeHTML(value)
-{
- function replaceChars(ch)
- {
- switch (ch)
- {
- case "<":
- return "&lt;";
- case ">":
- return "&gt;";
- case "&":
- return "&amp;";
- case "'":
- return "&#39;";
- case '"':
- return "&quot;";
- }
- return "?";
- };
- return String(value).replace(/[<>&"']/g, replaceChars);
-}
-
-this.escapeHTML = escapeHTML;
-
-this.cropString = function(text, limit)
-{
- text = text + "";
-
- if (!limit)
- var halfLimit = 50;
- else
- var halfLimit = limit / 2;
-
- if (text.length > limit)
- return this.escapeNewLines(text.substr(0, halfLimit) + "..." + text.substr(text.length-halfLimit));
- else
- return this.escapeNewLines(text);
-};
-
-this.isWhitespace = function(text)
-{
- return !reNotWhitespace.exec(text);
-};
-
-this.splitLines = function(text)
-{
- var reSplitLines2 = /.*(:?\r\n|\n|\r)?/mg;
- var lines;
- if (text.match)
- {
- lines = text.match(reSplitLines2);
- }
- else
- {
- var str = text+"";
- lines = str.match(reSplitLines2);
- }
- lines.pop();
- return lines;
-};
-
-
-// ************************************************************************************************
-
-this.safeToString = function(ob)
-{
- if (this.isIE)
- {
- try
- {
- // FIXME: xxxpedro this is failing in IE for the global "external" object
- return ob + "";
- }
- catch(E)
- {
- FBTrace.sysout("Lib.safeToString() failed for ", ob);
- return "";
- }
- }
-
- try
- {
- if (ob && "toString" in ob && typeof ob.toString == "function")
- return ob.toString();
- }
- catch (exc)
- {
- // xxxpedro it is not safe to use ob+""?
- return ob + "";
- ///return "[an object with no toString() function]";
- }
-};
-
-// ************************************************************************************************
-
-this.hasProperties = function(ob)
-{
- try
- {
- for (var name in ob)
- return true;
- } catch (exc) {}
- return false;
-};
-
-// ************************************************************************************************
-// String Util
-
-var reTrim = /^\s+|\s+$/g;
-this.trim = function(s)
-{
- return s.replace(reTrim, "");
-};
-
-
-// ************************************************************************************************
-// Empty
-
-this.emptyFn = function(){};
-
-
-
-// ************************************************************************************************
-// Visibility
-
-this.isVisible = function(elt)
-{
- /*
- if (elt instanceof XULElement)
- {
- //FBTrace.sysout("isVisible elt.offsetWidth: "+elt.offsetWidth+" offsetHeight:"+ elt.offsetHeight+" localName:"+ elt.localName+" nameSpace:"+elt.nameSpaceURI+"\n");
- return (!elt.hidden && !elt.collapsed);
- }
- /**/
-
- return this.getStyle(elt, "visibility") != "hidden" &&
- ( elt.offsetWidth > 0 || elt.offsetHeight > 0
- || elt.tagName in invisibleTags
- || elt.namespaceURI == "http://www.w3.org/2000/svg"
- || elt.namespaceURI == "http://www.w3.org/1998/Math/MathML" );
-};
-
-this.collapse = function(elt, collapsed)
-{
- // IE6 doesn't support the [collapsed] CSS selector. IE7 does support the selector,
- // but it is causing a bug (the element disappears when you set the "collapsed"
- // attribute, but it doesn't appear when you remove the attribute. So, for those
- // cases, we need to use the class attribute.
- if (this.isIElt8)
- {
- if (collapsed)
- this.setClass(elt, "collapsed");
- else
- this.removeClass(elt, "collapsed");
- }
- else
- elt.setAttribute("collapsed", collapsed ? "true" : "false");
-};
-
-this.obscure = function(elt, obscured)
-{
- if (obscured)
- this.setClass(elt, "obscured");
- else
- this.removeClass(elt, "obscured");
-};
-
-this.hide = function(elt, hidden)
-{
- elt.style.visibility = hidden ? "hidden" : "visible";
-};
-
-this.clearNode = function(node)
-{
- var nodeName = " " + node.nodeName.toLowerCase() + " ";
- var ignoreTags = " table tbody thead tfoot th tr td ";
-
- // IE can't use innerHTML of table elements
- if (this.isIE && ignoreTags.indexOf(nodeName) != -1)
- this.eraseNode(node);
- else
- node.innerHTML = "";
-};
-
-this.eraseNode = function(node)
-{
- while (node.lastChild)
- node.removeChild(node.lastChild);
-};
-
-// ************************************************************************************************
-// Window iteration
-
-this.iterateWindows = function(win, handler)
-{
- if (!win || !win.document)
- return;
-
- handler(win);
-
- if (win == top || !win.frames) return; // XXXjjb hack for chromeBug
-
- for (var i = 0; i < win.frames.length; ++i)
- {
- var subWin = win.frames[i];
- if (subWin != win)
- this.iterateWindows(subWin, handler);
- }
-};
-
-this.getRootWindow = function(win)
-{
- for (; win; win = win.parent)
- {
- if (!win.parent || win == win.parent || !this.instanceOf(win.parent, "Window"))
- return win;
- }
- return null;
-};
-
-// ************************************************************************************************
-// Graphics
-
-this.getClientOffset = function(elt)
-{
- var addOffset = function addOffset(elt, coords, view)
- {
- var p = elt.offsetParent;
-
- ///var style = isIE ? elt.currentStyle : view.getComputedStyle(elt, "");
- var chrome = Firebug.chrome;
-
- if (elt.offsetLeft)
- ///coords.x += elt.offsetLeft + parseInt(style.borderLeftWidth);
- coords.x += elt.offsetLeft + chrome.getMeasurementInPixels(elt, "borderLeft");
- if (elt.offsetTop)
- ///coords.y += elt.offsetTop + parseInt(style.borderTopWidth);
- coords.y += elt.offsetTop + chrome.getMeasurementInPixels(elt, "borderTop");
-
- if (p)
- {
- if (p.nodeType == 1)
- addOffset(p, coords, view);
- }
- else
- {
- var otherView = isIE ? elt.ownerDocument.parentWindow : elt.ownerDocument.defaultView;
- // IE will fail when reading the frameElement property of a popup window.
- // We don't need it anyway once it is outside the (popup) viewport, so we're
- // ignoring the frameElement check when the window is a popup
- if (!otherView.opener && otherView.frameElement)
- addOffset(otherView.frameElement, coords, otherView);
- }
- };
-
- var isIE = this.isIE;
- var coords = {x: 0, y: 0};
- if (elt)
- {
- var view = isIE ? elt.ownerDocument.parentWindow : elt.ownerDocument.defaultView;
- addOffset(elt, coords, view);
- }
-
- return coords;
-};
-
-this.getViewOffset = function(elt, singleFrame)
-{
- function addOffset(elt, coords, view)
- {
- var p = elt.offsetParent;
- coords.x += elt.offsetLeft - (p ? p.scrollLeft : 0);
- coords.y += elt.offsetTop - (p ? p.scrollTop : 0);
-
- if (p)
- {
- if (p.nodeType == 1)
- {
- var parentStyle = view.getComputedStyle(p, "");
- if (parentStyle.position != "static")
- {
- coords.x += parseInt(parentStyle.borderLeftWidth);
- coords.y += parseInt(parentStyle.borderTopWidth);
-
- if (p.localName == "TABLE")
- {
- coords.x += parseInt(parentStyle.paddingLeft);
- coords.y += parseInt(parentStyle.paddingTop);
- }
- else if (p.localName == "BODY")
- {
- var style = view.getComputedStyle(elt, "");
- coords.x += parseInt(style.marginLeft);
- coords.y += parseInt(style.marginTop);
- }
- }
- else if (p.localName == "BODY")
- {
- coords.x += parseInt(parentStyle.borderLeftWidth);
- coords.y += parseInt(parentStyle.borderTopWidth);
- }
-
- var parent = elt.parentNode;
- while (p != parent)
- {
- coords.x -= parent.scrollLeft;
- coords.y -= parent.scrollTop;
- parent = parent.parentNode;
- }
- addOffset(p, coords, view);
- }
- }
- else
- {
- if (elt.localName == "BODY")
- {
- var style = view.getComputedStyle(elt, "");
- coords.x += parseInt(style.borderLeftWidth);
- coords.y += parseInt(style.borderTopWidth);
-
- var htmlStyle = view.getComputedStyle(elt.parentNode, "");
- coords.x -= parseInt(htmlStyle.paddingLeft);
- coords.y -= parseInt(htmlStyle.paddingTop);
- }
-
- if (elt.scrollLeft)
- coords.x += elt.scrollLeft;
- if (elt.scrollTop)
- coords.y += elt.scrollTop;
-
- var win = elt.ownerDocument.defaultView;
- if (win && (!singleFrame && win.frameElement))
- addOffset(win.frameElement, coords, win);
- }
-
- }
-
- var coords = {x: 0, y: 0};
- if (elt)
- addOffset(elt, coords, elt.ownerDocument.defaultView);
-
- return coords;
-};
-
-this.getLTRBWH = function(elt)
-{
- var bcrect,
- dims = {"left": 0, "top": 0, "right": 0, "bottom": 0, "width": 0, "height": 0};
-
- if (elt)
- {
- bcrect = elt.getBoundingClientRect();
- dims.left = bcrect.left;
- dims.top = bcrect.top;
- dims.right = bcrect.right;
- dims.bottom = bcrect.bottom;
-
- if(bcrect.width)
- {
- dims.width = bcrect.width;
- dims.height = bcrect.height;
- }
- else
- {
- dims.width = dims.right - dims.left;
- dims.height = dims.bottom - dims.top;
- }
- }
- return dims;
-};
-
-this.applyBodyOffsets = function(elt, clientRect)
-{
- var od = elt.ownerDocument;
- if (!od.body)
- return clientRect;
-
- var style = od.defaultView.getComputedStyle(od.body, null);
-
- var pos = style.getPropertyValue('position');
- if(pos === 'absolute' || pos === 'relative')
- {
- var borderLeft = parseInt(style.getPropertyValue('border-left-width').replace('px', ''),10) || 0;
- var borderTop = parseInt(style.getPropertyValue('border-top-width').replace('px', ''),10) || 0;
- var paddingLeft = parseInt(style.getPropertyValue('padding-left').replace('px', ''),10) || 0;
- var paddingTop = parseInt(style.getPropertyValue('padding-top').replace('px', ''),10) || 0;
- var marginLeft = parseInt(style.getPropertyValue('margin-left').replace('px', ''),10) || 0;
- var marginTop = parseInt(style.getPropertyValue('margin-top').replace('px', ''),10) || 0;
-
- var offsetX = borderLeft + paddingLeft + marginLeft;
- var offsetY = borderTop + paddingTop + marginTop;
-
- clientRect.left -= offsetX;
- clientRect.top -= offsetY;
- clientRect.right -= offsetX;
- clientRect.bottom -= offsetY;
- }
-
- return clientRect;
-};
-
-this.getOffsetSize = function(elt)
-{
- return {width: elt.offsetWidth, height: elt.offsetHeight};
-};
-
-this.getOverflowParent = function(element)
-{
- for (var scrollParent = element.parentNode; scrollParent; scrollParent = scrollParent.offsetParent)
- {
- if (scrollParent.scrollHeight > scrollParent.offsetHeight)
- return scrollParent;
- }
-};
-
-this.isScrolledToBottom = function(element)
-{
- var onBottom = (element.scrollTop + element.offsetHeight) == element.scrollHeight;
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("isScrolledToBottom offsetHeight: "+element.offsetHeight +" onBottom:"+onBottom);
- return onBottom;
-};
-
-this.scrollToBottom = function(element)
-{
- element.scrollTop = element.scrollHeight;
-
- if (FBTrace.DBG_CONSOLE)
- {
- FBTrace.sysout("scrollToBottom reset scrollTop "+element.scrollTop+" = "+element.scrollHeight);
- if (element.scrollHeight == element.offsetHeight)
- FBTrace.sysout("scrollToBottom attempt to scroll non-scrollable element "+element, element);
- }
-
- return (element.scrollTop == element.scrollHeight);
-};
-
-this.move = function(element, x, y)
-{
- element.style.left = x + "px";
- element.style.top = y + "px";
-};
-
-this.resize = function(element, w, h)
-{
- element.style.width = w + "px";
- element.style.height = h + "px";
-};
-
-this.linesIntoCenterView = function(element, scrollBox) // {before: int, after: int}
-{
- if (!scrollBox)
- scrollBox = this.getOverflowParent(element);
-
- if (!scrollBox)
- return;
-
- var offset = this.getClientOffset(element);
-
- var topSpace = offset.y - scrollBox.scrollTop;
- var bottomSpace = (scrollBox.scrollTop + scrollBox.clientHeight)
- - (offset.y + element.offsetHeight);
-
- if (topSpace < 0 || bottomSpace < 0)
- {
- var split = (scrollBox.clientHeight/2);
- var centerY = offset.y - split;
- scrollBox.scrollTop = centerY;
- topSpace = split;
- bottomSpace = split - element.offsetHeight;
- }
-
- return {before: Math.round((topSpace/element.offsetHeight) + 0.5),
- after: Math.round((bottomSpace/element.offsetHeight) + 0.5) };
-};
-
-this.scrollIntoCenterView = function(element, scrollBox, notX, notY)
-{
- if (!element)
- return;
-
- if (!scrollBox)
- scrollBox = this.getOverflowParent(element);
-
- if (!scrollBox)
- return;
-
- var offset = this.getClientOffset(element);
-
- if (!notY)
- {
- var topSpace = offset.y - scrollBox.scrollTop;
- var bottomSpace = (scrollBox.scrollTop + scrollBox.clientHeight)
- - (offset.y + element.offsetHeight);
-
- if (topSpace < 0 || bottomSpace < 0)
- {
- var centerY = offset.y - (scrollBox.clientHeight/2);
- scrollBox.scrollTop = centerY;
- }
- }
-
- if (!notX)
- {
- var leftSpace = offset.x - scrollBox.scrollLeft;
- var rightSpace = (scrollBox.scrollLeft + scrollBox.clientWidth)
- - (offset.x + element.clientWidth);
-
- if (leftSpace < 0 || rightSpace < 0)
- {
- var centerX = offset.x - (scrollBox.clientWidth/2);
- scrollBox.scrollLeft = centerX;
- }
- }
- if (FBTrace.DBG_SOURCEFILES)
- FBTrace.sysout("lib.scrollIntoCenterView ","Element:"+element.innerHTML);
-};
-
-
-// ************************************************************************************************
-// CSS
-
-var cssKeywordMap = null;
-var cssPropNames = null;
-var cssColorNames = null;
-var imageRules = null;
-
-this.getCSSKeywordsByProperty = function(propName)
-{
- if (!cssKeywordMap)
- {
- cssKeywordMap = {};
-
- for (var name in this.cssInfo)
- {
- var list = [];
-
- var types = this.cssInfo[name];
- for (var i = 0; i < types.length; ++i)
- {
- var keywords = this.cssKeywords[types[i]];
- if (keywords)
- list.push.apply(list, keywords);
- }
-
- cssKeywordMap[name] = list;
- }
- }
-
- return propName in cssKeywordMap ? cssKeywordMap[propName] : [];
-};
-
-this.getCSSPropertyNames = function()
-{
- if (!cssPropNames)
- {
- cssPropNames = [];
-
- for (var name in this.cssInfo)
- cssPropNames.push(name);
- }
-
- return cssPropNames;
-};
-
-this.isColorKeyword = function(keyword)
-{
- if (keyword == "transparent")
- return false;
-
- if (!cssColorNames)
- {
- cssColorNames = [];
-
- var colors = this.cssKeywords["color"];
- for (var i = 0; i < colors.length; ++i)
- cssColorNames.push(colors[i].toLowerCase());
-
- var systemColors = this.cssKeywords["systemColor"];
- for (var i = 0; i < systemColors.length; ++i)
- cssColorNames.push(systemColors[i].toLowerCase());
- }
-
- return cssColorNames.indexOf ? // Array.indexOf is not available in IE
- cssColorNames.indexOf(keyword.toLowerCase()) != -1 :
- (" " + cssColorNames.join(" ") + " ").indexOf(" " + keyword.toLowerCase() + " ") != -1;
-};
-
-this.isImageRule = function(rule)
-{
- if (!imageRules)
- {
- imageRules = [];
-
- for (var i in this.cssInfo)
- {
- var r = i.toLowerCase();
- var suffix = "image";
- if (r.match(suffix + "$") == suffix || r == "background")
- imageRules.push(r);
- }
- }
-
- return imageRules.indexOf ? // Array.indexOf is not available in IE
- imageRules.indexOf(rule.toLowerCase()) != -1 :
- (" " + imageRules.join(" ") + " ").indexOf(" " + rule.toLowerCase() + " ") != -1;
-};
-
-this.copyTextStyles = function(fromNode, toNode, style)
-{
- var view = this.isIE ?
- fromNode.ownerDocument.parentWindow :
- fromNode.ownerDocument.defaultView;
-
- if (view)
- {
- if (!style)
- style = this.isIE ? fromNode.currentStyle : view.getComputedStyle(fromNode, "");
-
- toNode.style.fontFamily = style.fontFamily;
-
- // TODO: xxxpedro need to create a FBL.getComputedStyle() because IE
- // returns wrong computed styles for inherited properties (like font-*)
- //
- // Also would be good to create a FBL.getStyle()
- toNode.style.fontSize = style.fontSize;
- toNode.style.fontWeight = style.fontWeight;
- toNode.style.fontStyle = style.fontStyle;
-
- return style;
- }
-};
-
-this.copyBoxStyles = function(fromNode, toNode, style)
-{
- var view = this.isIE ?
- fromNode.ownerDocument.parentWindow :
- fromNode.ownerDocument.defaultView;
-
- if (view)
- {
- if (!style)
- style = this.isIE ? fromNode.currentStyle : view.getComputedStyle(fromNode, "");
-
- toNode.style.marginTop = style.marginTop;
- toNode.style.marginRight = style.marginRight;
- toNode.style.marginBottom = style.marginBottom;
- toNode.style.marginLeft = style.marginLeft;
- toNode.style.borderTopWidth = style.borderTopWidth;
- toNode.style.borderRightWidth = style.borderRightWidth;
- toNode.style.borderBottomWidth = style.borderBottomWidth;
- toNode.style.borderLeftWidth = style.borderLeftWidth;
-
- return style;
- }
-};
-
-this.readBoxStyles = function(style)
-{
- var styleNames = {
- "margin-top": "marginTop", "margin-right": "marginRight",
- "margin-left": "marginLeft", "margin-bottom": "marginBottom",
- "border-top-width": "borderTop", "border-right-width": "borderRight",
- "border-left-width": "borderLeft", "border-bottom-width": "borderBottom",
- "padding-top": "paddingTop", "padding-right": "paddingRight",
- "padding-left": "paddingLeft", "padding-bottom": "paddingBottom",
- "z-index": "zIndex"
- };
-
- var styles = {};
- for (var styleName in styleNames)
- styles[styleNames[styleName]] = parseInt(style.getPropertyCSSValue(styleName).cssText) || 0;
- if (FBTrace.DBG_INSPECT)
- FBTrace.sysout("readBoxStyles ", styles);
- return styles;
-};
-
-this.getBoxFromStyles = function(style, element)
-{
- var args = this.readBoxStyles(style);
- args.width = element.offsetWidth
- - (args.paddingLeft+args.paddingRight+args.borderLeft+args.borderRight);
- args.height = element.offsetHeight
- - (args.paddingTop+args.paddingBottom+args.borderTop+args.borderBottom);
- return args;
-};
-
-this.getElementCSSSelector = function(element)
-{
- var label = element.localName.toLowerCase();
- if (element.id)
- label += "#" + element.id;
- if (element.hasAttribute("class"))
- label += "." + element.getAttribute("class").split(" ")[0];
-
- return label;
-};
-
-this.getURLForStyleSheet= function(styleSheet)
-{
- //http://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-StyleSheet. For inline style sheets, the value of this attribute is null.
- return (styleSheet.href ? styleSheet.href : styleSheet.ownerNode.ownerDocument.URL);
-};
-
-this.getDocumentForStyleSheet = function(styleSheet)
-{
- while (styleSheet.parentStyleSheet && !styleSheet.ownerNode)
- {
- styleSheet = styleSheet.parentStyleSheet;
- }
- if (styleSheet.ownerNode)
- return styleSheet.ownerNode.ownerDocument;
-};
-
-/**
- * Retrieves the instance number for a given style sheet. The instance number
- * is sheet's index within the set of all other sheets whose URL is the same.
- */
-this.getInstanceForStyleSheet = function(styleSheet, ownerDocument)
-{
- // System URLs are always unique (or at least we are making this assumption)
- if (FBL.isSystemStyleSheet(styleSheet))
- return 0;
-
- // ownerDocument is an optional hint for performance
- if (FBTrace.DBG_CSS) FBTrace.sysout("getInstanceForStyleSheet: " + styleSheet.href + " " + styleSheet.media.mediaText + " " + (styleSheet.ownerNode && FBL.getElementXPath(styleSheet.ownerNode)), ownerDocument);
- ownerDocument = ownerDocument || FBL.getDocumentForStyleSheet(styleSheet);
-
- var ret = 0,
- styleSheets = ownerDocument.styleSheets,
- href = styleSheet.href;
- for (var i = 0; i < styleSheets.length; i++)
- {
- var curSheet = styleSheets[i];
- if (FBTrace.DBG_CSS) FBTrace.sysout("getInstanceForStyleSheet: compare href " + i + " " + curSheet.href + " " + curSheet.media.mediaText + " " + (curSheet.ownerNode && FBL.getElementXPath(curSheet.ownerNode)));
- if (curSheet == styleSheet)
- break;
- if (curSheet.href == href)
- ret++;
- }
- return ret;
-};
-
-// ************************************************************************************************
-// HTML and XML Serialization
-
-
-var getElementType = this.getElementType = function(node)
-{
- if (isElementXUL(node))
- return 'xul';
- else if (isElementSVG(node))
- return 'svg';
- else if (isElementMathML(node))
- return 'mathml';
- else if (isElementXHTML(node))
- return 'xhtml';
- else if (isElementHTML(node))
- return 'html';
-};
-
-var getElementSimpleType = this.getElementSimpleType = function(node)
-{
- if (isElementSVG(node))
- return 'svg';
- else if (isElementMathML(node))
- return 'mathml';
- else
- return 'html';
-};
-
-var isElementHTML = this.isElementHTML = function(node)
-{
- return node.nodeName == node.nodeName.toUpperCase();
-};
-
-var isElementXHTML = this.isElementXHTML = function(node)
-{
- return node.nodeName == node.nodeName.toLowerCase();
-};
-
-var isElementMathML = this.isElementMathML = function(node)
-{
- return node.namespaceURI == 'http://www.w3.org/1998/Math/MathML';
-};
-
-var isElementSVG = this.isElementSVG = function(node)
-{
- return node.namespaceURI == 'http://www.w3.org/2000/svg';
-};
-
-var isElementXUL = this.isElementXUL = function(node)
-{
- return node instanceof XULElement;
-};
-
-this.isSelfClosing = function(element)
-{
- if (isElementSVG(element) || isElementMathML(element))
- return true;
- var tag = element.localName.toLowerCase();
- return (this.selfClosingTags.hasOwnProperty(tag));
-};
-
-this.getElementHTML = function(element)
-{
- var self=this;
- function toHTML(elt)
- {
- if (elt.nodeType == Node.ELEMENT_NODE)
- {
- if (unwrapObject(elt).firebugIgnore)
- return;
-
- html.push('<', elt.nodeName.toLowerCase());
-
- for (var i = 0; i < elt.attributes.length; ++i)
- {
- var attr = elt.attributes[i];
-
- // Hide attributes set by Firebug
- if (attr.localName.indexOf("firebug-") == 0)
- continue;
-
- // MathML
- if (attr.localName.indexOf("-moz-math") == 0)
- {
- // just hide for now
- continue;
- }
-
- html.push(' ', attr.nodeName, '="', escapeForElementAttribute(attr.nodeValue),'"');
- }
-
- if (elt.firstChild)
- {
- html.push('>');
-
- var pureText=true;
- for (var child = element.firstChild; child; child = child.nextSibling)
- pureText=pureText && (child.nodeType == Node.TEXT_NODE);
-
- if (pureText)
- html.push(escapeForHtmlEditor(elt.textContent));
- else {
- for (var child = elt.firstChild; child; child = child.nextSibling)
- toHTML(child);
- }
-
- html.push('</', elt.nodeName.toLowerCase(), '>');
- }
- else if (isElementSVG(elt) || isElementMathML(elt))
- {
- html.push('/>');
- }
- else if (self.isSelfClosing(elt))
- {
- html.push((isElementXHTML(elt))?'/>':'>');
- }
- else
- {
- html.push('></', elt.nodeName.toLowerCase(), '>');
- }
- }
- else if (elt.nodeType == Node.TEXT_NODE)
- html.push(escapeForTextNode(elt.textContent));
- else if (elt.nodeType == Node.CDATA_SECTION_NODE)
- html.push('<![CDATA[', elt.nodeValue, ']]>');
- else if (elt.nodeType == Node.COMMENT_NODE)
- html.push('<!--', elt.nodeValue, '-->');
- }
-
- var html = [];
- toHTML(element);
- return html.join("");
-};
-
-this.getElementXML = function(element)
-{
- function toXML(elt)
- {
- if (elt.nodeType == Node.ELEMENT_NODE)
- {
- if (unwrapObject(elt).firebugIgnore)
- return;
-
- xml.push('<', elt.nodeName.toLowerCase());
-
- for (var i = 0; i < elt.attributes.length; ++i)
- {
- var attr = elt.attributes[i];
-
- // Hide attributes set by Firebug
- if (attr.localName.indexOf("firebug-") == 0)
- continue;
-
- // MathML
- if (attr.localName.indexOf("-moz-math") == 0)
- {
- // just hide for now
- continue;
- }
-
- xml.push(' ', attr.nodeName, '="', escapeForElementAttribute(attr.nodeValue),'"');
- }
-
- if (elt.firstChild)
- {
- xml.push('>');
-
- for (var child = elt.firstChild; child; child = child.nextSibling)
- toXML(child);
-
- xml.push('</', elt.nodeName.toLowerCase(), '>');
- }
- else
- xml.push('/>');
- }
- else if (elt.nodeType == Node.TEXT_NODE)
- xml.push(elt.nodeValue);
- else if (elt.nodeType == Node.CDATA_SECTION_NODE)
- xml.push('<![CDATA[', elt.nodeValue, ']]>');
- else if (elt.nodeType == Node.COMMENT_NODE)
- xml.push('<!--', elt.nodeValue, '-->');
- }
-
- var xml = [];
- toXML(element);
- return xml.join("");
-};
-
-
-// ************************************************************************************************
-// CSS classes
-
-this.hasClass = function(node, name) // className, className, ...
-{
- // TODO: xxxpedro when lib.hasClass is called with more than 2 arguments?
- // this function can be optimized a lot if assumed 2 arguments only,
- // which seems to be what happens 99% of the time
- if (arguments.length == 2)
- return (' '+node.className+' ').indexOf(' '+name+' ') != -1;
-
- if (!node || node.nodeType != 1)
- return false;
- else
- {
- for (var i=1; i<arguments.length; ++i)
- {
- var name = arguments[i];
- var re = new RegExp("(^|\\s)"+name+"($|\\s)");
- if (!re.exec(node.className))
- return false;
- }
-
- return true;
- }
-};
-
-this.old_hasClass = function(node, name) // className, className, ...
-{
- if (!node || node.nodeType != 1)
- return false;
- else
- {
- for (var i=1; i<arguments.length; ++i)
- {
- var name = arguments[i];
- var re = new RegExp("(^|\\s)"+name+"($|\\s)");
- if (!re.exec(node.className))
- return false;
- }
-
- return true;
- }
-};
-
-this.setClass = function(node, name)
-{
- if (node && (' '+node.className+' ').indexOf(' '+name+' ') == -1)
- ///if (node && !this.hasClass(node, name))
- node.className += " " + name;
-};
-
-this.getClassValue = function(node, name)
-{
- var re = new RegExp(name+"-([^ ]+)");
- var m = re.exec(node.className);
- return m ? m[1] : "";
-};
-
-this.removeClass = function(node, name)
-{
- if (node && node.className)
- {
- var index = node.className.indexOf(name);
- if (index >= 0)
- {
- var size = name.length;
- node.className = node.className.substr(0,index-1) + node.className.substr(index+size);
- }
- }
-};
-
-this.toggleClass = function(elt, name)
-{
- if ((' '+elt.className+' ').indexOf(' '+name+' ') != -1)
- ///if (this.hasClass(elt, name))
- this.removeClass(elt, name);
- else
- this.setClass(elt, name);
-};
-
-this.setClassTimed = function(elt, name, context, timeout)
-{
- if (!timeout)
- timeout = 1300;
-
- if (elt.__setClassTimeout)
- context.clearTimeout(elt.__setClassTimeout);
- else
- this.setClass(elt, name);
-
- elt.__setClassTimeout = context.setTimeout(function()
- {
- delete elt.__setClassTimeout;
-
- FBL.removeClass(elt, name);
- }, timeout);
-};
-
-this.cancelClassTimed = function(elt, name, context)
-{
- if (elt.__setClassTimeout)
- {
- FBL.removeClass(elt, name);
- context.clearTimeout(elt.__setClassTimeout);
- delete elt.__setClassTimeout;
- }
-};
-
-
-// ************************************************************************************************
-// DOM queries
-
-this.$ = function(id, doc)
-{
- if (doc)
- return doc.getElementById(id);
- else
- {
- return FBL.Firebug.chrome.document.getElementById(id);
- }
-};
-
-this.$$ = function(selector, doc)
-{
- if (doc || !FBL.Firebug.chrome)
- return FBL.Firebug.Selector(selector, doc);
- else
- {
- return FBL.Firebug.Selector(selector, FBL.Firebug.chrome.document);
- }
-};
-
-this.getChildByClass = function(node) // ,classname, classname, classname...
-{
- for (var i = 1; i < arguments.length; ++i)
- {
- var className = arguments[i];
- var child = node.firstChild;
- node = null;
- for (; child; child = child.nextSibling)
- {
- if (this.hasClass(child, className))
- {
- node = child;
- break;
- }
- }
- }
-
- return node;
-};
-
-this.getAncestorByClass = function(node, className)
-{
- for (var parent = node; parent; parent = parent.parentNode)
- {
- if (this.hasClass(parent, className))
- return parent;
- }
-
- return null;
-};
-
-
-this.getElementsByClass = function(node, className)
-{
- var result = [];
-
- for (var child = node.firstChild; child; child = child.nextSibling)
- {
- if (this.hasClass(child, className))
- result.push(child);
- }
-
- return result;
-};
-
-this.getElementByClass = function(node, className) // className, className, ...
-{
- var args = cloneArray(arguments); args.splice(0, 1);
- for (var child = node.firstChild; child; child = child.nextSibling)
- {
- var args1 = cloneArray(args); args1.unshift(child);
- if (FBL.hasClass.apply(null, args1))
- return child;
- else
- {
- var found = FBL.getElementByClass.apply(null, args1);
- if (found)
- return found;
- }
- }
-
- return null;
-};
-
-this.isAncestor = function(node, potentialAncestor)
-{
- for (var parent = node; parent; parent = parent.parentNode)
- {
- if (parent == potentialAncestor)
- return true;
- }
-
- return false;
-};
-
-this.getNextElement = function(node)
-{
- while (node && node.nodeType != 1)
- node = node.nextSibling;
-
- return node;
-};
-
-this.getPreviousElement = function(node)
-{
- while (node && node.nodeType != 1)
- node = node.previousSibling;
-
- return node;
-};
-
-this.getBody = function(doc)
-{
- if (doc.body)
- return doc.body;
-
- var body = doc.getElementsByTagName("body")[0];
- if (body)
- return body;
-
- return doc.firstChild; // For non-HTML docs
-};
-
-this.findNextDown = function(node, criteria)
-{
- if (!node)
- return null;
-
- for (var child = node.firstChild; child; child = child.nextSibling)
- {
- if (criteria(child))
- return child;
-
- var next = this.findNextDown(child, criteria);
- if (next)
- return next;
- }
-};
-
-this.findPreviousUp = function(node, criteria)
-{
- if (!node)
- return null;
-
- for (var child = node.lastChild; child; child = child.previousSibling)
- {
- var next = this.findPreviousUp(child, criteria);
- if (next)
- return next;
-
- if (criteria(child))
- return child;
- }
-};
-
-this.findNext = function(node, criteria, upOnly, maxRoot)
-{
- if (!node)
- return null;
-
- if (!upOnly)
- {
- var next = this.findNextDown(node, criteria);
- if (next)
- return next;
- }
-
- for (var sib = node.nextSibling; sib; sib = sib.nextSibling)
- {
- if (criteria(sib))
- return sib;
-
- var next = this.findNextDown(sib, criteria);
- if (next)
- return next;
- }
-
- if (node.parentNode && node.parentNode != maxRoot)
- return this.findNext(node.parentNode, criteria, true);
-};
-
-this.findPrevious = function(node, criteria, downOnly, maxRoot)
-{
- if (!node)
- return null;
-
- for (var sib = node.previousSibling; sib; sib = sib.previousSibling)
- {
- var prev = this.findPreviousUp(sib, criteria);
- if (prev)
- return prev;
-
- if (criteria(sib))
- return sib;
- }
-
- if (!downOnly)
- {
- var next = this.findPreviousUp(node, criteria);
- if (next)
- return next;
- }
-
- if (node.parentNode && node.parentNode != maxRoot)
- {
- if (criteria(node.parentNode))
- return node.parentNode;
-
- return this.findPrevious(node.parentNode, criteria, true);
- }
-};
-
-this.getNextByClass = function(root, state)
-{
- var iter = function iter(node) { return node.nodeType == 1 && FBL.hasClass(node, state); };
- return this.findNext(root, iter);
-};
-
-this.getPreviousByClass = function(root, state)
-{
- var iter = function iter(node) { return node.nodeType == 1 && FBL.hasClass(node, state); };
- return this.findPrevious(root, iter);
-};
-
-this.isElement = function(o)
-{
- try {
- return o && this.instanceOf(o, "Element");
- }
- catch (ex) {
- return false;
- }
-};
-
-
-// ************************************************************************************************
-// DOM Modification
-
-// TODO: xxxpedro use doc fragments in Context API
-var appendFragment = null;
-
-this.appendInnerHTML = function(element, html, referenceElement)
-{
- // if undefined, we must convert it to null otherwise it will throw an error in IE
- // when executing element.insertBefore(firstChild, referenceElement)
- referenceElement = referenceElement || null;
-
- var doc = element.ownerDocument;
-
- // doc.createRange not available in IE
- if (doc.createRange)
- {
- var range = doc.createRange(); // a helper object
- range.selectNodeContents(element); // the environment to interpret the html
-
- var fragment = range.createContextualFragment(html); // parse
- var firstChild = fragment.firstChild;
- element.insertBefore(fragment, referenceElement);
- }
- else
- {
- if (!appendFragment || appendFragment.ownerDocument != doc)
- appendFragment = doc.createDocumentFragment();
-
- var div = doc.createElement("div");
- div.innerHTML = html;
-
- var firstChild = div.firstChild;
- while (div.firstChild)
- appendFragment.appendChild(div.firstChild);
-
- element.insertBefore(appendFragment, referenceElement);
-
- div = null;
- }
-
- return firstChild;
-};
-
-
-// ************************************************************************************************
-// DOM creation
-
-this.createElement = function(tagName, properties)
-{
- properties = properties || {};
- var doc = properties.document || FBL.Firebug.chrome.document;
-
- var element = doc.createElement(tagName);
-
- for(var name in properties)
- {
- if (name != "document")
- {
- element[name] = properties[name];
- }
- }
-
- return element;
-};
-
-this.createGlobalElement = function(tagName, properties)
-{
- properties = properties || {};
- var doc = FBL.Env.browser.document;
-
- var element = this.NS && doc.createElementNS ?
- doc.createElementNS(FBL.NS, tagName) :
- doc.createElement(tagName);
-
- for(var name in properties)
- {
- var propname = name;
- if (FBL.isIE && name == "class") propname = "className";
-
- if (name != "document")
- {
- element.setAttribute(propname, properties[name]);
- }
- }
-
- return element;
-};
-
-//************************************************************************************************
-
-this.safeGetWindowLocation = function(window)
-{
- try
- {
- if (window)
- {
- if (window.closed)
- return "(window.closed)";
- if ("location" in window)
- return window.location+"";
- else
- return "(no window.location)";
- }
- else
- return "(no context.window)";
- }
- catch(exc)
- {
- if (FBTrace.DBG_WINDOWS || FBTrace.DBG_ERRORS)
- FBTrace.sysout("TabContext.getWindowLocation failed "+exc, exc);
- FBTrace.sysout("TabContext.getWindowLocation failed window:", window);
- return "(getWindowLocation: "+exc+")";
- }
-};
-
-// ************************************************************************************************
-// Events
-
-this.isLeftClick = function(event)
-{
- return (this.isIE && event.type != "click" && event.type != "dblclick" ?
- event.button == 1 : // IE "click" and "dblclick" button model
- event.button == 0) && // others
- this.noKeyModifiers(event);
-};
-
-this.isMiddleClick = function(event)
-{
- return (this.isIE && event.type != "click" && event.type != "dblclick" ?
- event.button == 4 : // IE "click" and "dblclick" button model
- event.button == 1) &&
- this.noKeyModifiers(event);
-};
-
-this.isRightClick = function(event)
-{
- return (this.isIE && event.type != "click" && event.type != "dblclick" ?
- event.button == 2 : // IE "click" and "dblclick" button model
- event.button == 2) &&
- this.noKeyModifiers(event);
-};
-
-this.noKeyModifiers = function(event)
-{
- return !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey;
-};
-
-this.isControlClick = function(event)
-{
- return (this.isIE && event.type != "click" && event.type != "dblclick" ?
- event.button == 1 : // IE "click" and "dblclick" button model
- event.button == 0) &&
- this.isControl(event);
-};
-
-this.isShiftClick = function(event)
-{
- return (this.isIE && event.type != "click" && event.type != "dblclick" ?
- event.button == 1 : // IE "click" and "dblclick" button model
- event.button == 0) &&
- this.isShift(event);
-};
-
-this.isControl = function(event)
-{
- return (event.metaKey || event.ctrlKey) && !event.shiftKey && !event.altKey;
-};
-
-this.isAlt = function(event)
-{
- return event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey;
-};
-
-this.isAltClick = function(event)
-{
- return (this.isIE && event.type != "click" && event.type != "dblclick" ?
- event.button == 1 : // IE "click" and "dblclick" button model
- event.button == 0) &&
- this.isAlt(event);
-};
-
-this.isControlShift = function(event)
-{
- return (event.metaKey || event.ctrlKey) && event.shiftKey && !event.altKey;
-};
-
-this.isShift = function(event)
-{
- return event.shiftKey && !event.metaKey && !event.ctrlKey && !event.altKey;
-};
-
-this.addEvent = function(object, name, handler, useCapture)
-{
- if (object.addEventListener)
- object.addEventListener(name, handler, useCapture);
- else
- object.attachEvent("on"+name, handler);
-};
-
-this.removeEvent = function(object, name, handler, useCapture)
-{
- try
- {
- if (object.removeEventListener)
- object.removeEventListener(name, handler, useCapture);
- else
- object.detachEvent("on"+name, handler);
- }
- catch(e)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("FBL.removeEvent error: ", object, name);
- }
-};
-
-this.cancelEvent = function(e, preventDefault)
-{
- if (!e) return;
-
- if (preventDefault)
- {
- if (e.preventDefault)
- e.preventDefault();
- else
- e.returnValue = false;
- }
-
- if (e.stopPropagation)
- e.stopPropagation();
- else
- e.cancelBubble = true;
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-this.addGlobalEvent = function(name, handler)
-{
- var doc = this.Firebug.browser.document;
- var frames = this.Firebug.browser.window.frames;
-
- this.addEvent(doc, name, handler);
-
- if (this.Firebug.chrome.type == "popup")
- this.addEvent(this.Firebug.chrome.document, name, handler);
-
- for (var i = 0, frame; frame = frames[i]; i++)
- {
- try
- {
- this.addEvent(frame.document, name, handler);
- }
- catch(E)
- {
- // Avoid acess denied
- }
- }
-};
-
-this.removeGlobalEvent = function(name, handler)
-{
- var doc = this.Firebug.browser.document;
- var frames = this.Firebug.browser.window.frames;
-
- this.removeEvent(doc, name, handler);
-
- if (this.Firebug.chrome.type == "popup")
- this.removeEvent(this.Firebug.chrome.document, name, handler);
-
- for (var i = 0, frame; frame = frames[i]; i++)
- {
- try
- {
- this.removeEvent(frame.document, name, handler);
- }
- catch(E)
- {
- // Avoid acess denied
- }
- }
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-this.dispatch = function(listeners, name, args)
-{
- if (!listeners) return;
-
- try
- {/**/
- if (typeof listeners.length != "undefined")
- {
- if (FBTrace.DBG_DISPATCH) FBTrace.sysout("FBL.dispatch", name+" to "+listeners.length+" listeners");
-
- for (var i = 0; i < listeners.length; ++i)
- {
- var listener = listeners[i];
- if ( listener[name] )
- listener[name].apply(listener, args);
- }
- }
- else
- {
- if (FBTrace.DBG_DISPATCH) FBTrace.sysout("FBL.dispatch", name+" to listeners of an object");
-
- for (var prop in listeners)
- {
- var listener = listeners[prop];
- if ( listener[name] )
- listener[name].apply(listener, args);
- }
- }
- }
- catch (exc)
- {
- if (FBTrace.DBG_ERRORS)
- {
- FBTrace.sysout(" Exception in lib.dispatch "+ name, exc);
- //FBTrace.dumpProperties(" Exception in lib.dispatch listener", listener);
- }
- }
- /**/
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var disableTextSelectionHandler = function(event)
-{
- FBL.cancelEvent(event, true);
-
- return false;
-};
-
-this.disableTextSelection = function(e)
-{
- if (typeof e.onselectstart != "undefined") // IE
- this.addEvent(e, "selectstart", disableTextSelectionHandler);
-
- else // others
- {
- e.style.cssText = "user-select: none; -khtml-user-select: none; -moz-user-select: none;";
-
- // canceling the event in FF will prevent the menu popups to close when clicking over
- // text-disabled elements
- if (!this.isFirefox)
- this.addEvent(e, "mousedown", disableTextSelectionHandler);
- }
-
- e.style.cursor = "default";
-};
-
-this.restoreTextSelection = function(e)
-{
- if (typeof e.onselectstart != "undefined") // IE
- this.removeEvent(e, "selectstart", disableTextSelectionHandler);
-
- else // others
- {
- e.style.cssText = "cursor: default;";
-
- // canceling the event in FF will prevent the menu popups to close when clicking over
- // text-disabled elements
- if (!this.isFirefox)
- this.removeEvent(e, "mousedown", disableTextSelectionHandler);
- }
-};
-
-// ************************************************************************************************
-// DOM Events
-
-var eventTypes =
-{
- composition: [
- "composition",
- "compositionstart",
- "compositionend" ],
- contextmenu: [
- "contextmenu" ],
- drag: [
- "dragenter",
- "dragover",
- "dragexit",
- "dragdrop",
- "draggesture" ],
- focus: [
- "focus",
- "blur" ],
- form: [
- "submit",
- "reset",
- "change",
- "select",
- "input" ],
- key: [
- "keydown",
- "keyup",
- "keypress" ],
- load: [
- "load",
- "beforeunload",
- "unload",
- "abort",
- "error" ],
- mouse: [
- "mousedown",
- "mouseup",
- "click",
- "dblclick",
- "mouseover",
- "mouseout",
- "mousemove" ],
- mutation: [
- "DOMSubtreeModified",
- "DOMNodeInserted",
- "DOMNodeRemoved",
- "DOMNodeRemovedFromDocument",
- "DOMNodeInsertedIntoDocument",
- "DOMAttrModified",
- "DOMCharacterDataModified" ],
- paint: [
- "paint",
- "resize",
- "scroll" ],
- scroll: [
- "overflow",
- "underflow",
- "overflowchanged" ],
- text: [
- "text" ],
- ui: [
- "DOMActivate",
- "DOMFocusIn",
- "DOMFocusOut" ],
- xul: [
- "popupshowing",
- "popupshown",
- "popuphiding",
- "popuphidden",
- "close",
- "command",
- "broadcast",
- "commandupdate" ]
-};
-
-this.getEventFamily = function(eventType)
-{
- if (!this.families)
- {
- this.families = {};
-
- for (var family in eventTypes)
- {
- var types = eventTypes[family];
- for (var i = 0; i < types.length; ++i)
- this.families[types[i]] = family;
- }
- }
-
- return this.families[eventType];
-};
-
-
-// ************************************************************************************************
-// URLs
-
-this.getFileName = function(url)
-{
- var split = this.splitURLBase(url);
- return split.name;
-};
-
-this.splitURLBase = function(url)
-{
- if (this.isDataURL(url))
- return this.splitDataURL(url);
- return this.splitURLTrue(url);
-};
-
-this.splitDataURL = function(url)
-{
- var mark = url.indexOf(':', 3);
- if (mark != 4)
- return false; // the first 5 chars must be 'data:'
-
- var point = url.indexOf(',', mark+1);
- if (point < mark)
- return false; // syntax error
-
- var props = { encodedContent: url.substr(point+1) };
-
- var metadataBuffer = url.substr(mark+1, point);
- var metadata = metadataBuffer.split(';');
- for (var i = 0; i < metadata.length; i++)
- {
- var nv = metadata[i].split('=');
- if (nv.length == 2)
- props[nv[0]] = nv[1];
- }
-
- // Additional Firebug-specific properties
- if (props.hasOwnProperty('fileName'))
- {
- var caller_URL = decodeURIComponent(props['fileName']);
- var caller_split = this.splitURLTrue(caller_URL);
-
- if (props.hasOwnProperty('baseLineNumber')) // this means it's probably an eval()
- {
- props['path'] = caller_split.path;
- props['line'] = props['baseLineNumber'];
- var hint = decodeURIComponent(props['encodedContent'].substr(0,200)).replace(/\s*$/, "");
- props['name'] = 'eval->'+hint;
- }
- else
- {
- props['name'] = caller_split.name;
- props['path'] = caller_split.path;
- }
- }
- else
- {
- if (!props.hasOwnProperty('path'))
- props['path'] = "data:";
- if (!props.hasOwnProperty('name'))
- props['name'] = decodeURIComponent(props['encodedContent'].substr(0,200)).replace(/\s*$/, "");
- }
-
- return props;
-};
-
-this.splitURLTrue = function(url)
-{
- var m = reSplitFile.exec(url);
- if (!m)
- return {name: url, path: url};
- else if (!m[2])
- return {path: m[1], name: m[1]};
- else
- return {path: m[1], name: m[2]+m[3]};
-};
-
-this.getFileExtension = function(url)
-{
- if (!url)
- return null;
-
- // Remove query string from the URL if any.
- var queryString = url.indexOf("?");
- if (queryString != -1)
- url = url.substr(0, queryString);
-
- // Now get the file extension.
- var lastDot = url.lastIndexOf(".");
- return url.substr(lastDot+1);
-};
-
-this.isSystemURL = function(url)
-{
- if (!url) return true;
- if (url.length == 0) return true;
- if (url[0] == 'h') return false;
- if (url.substr(0, 9) == "resource:")
- return true;
- else if (url.substr(0, 16) == "chrome://firebug")
- return true;
- else if (url == "XPCSafeJSObjectWrapper.cpp")
- return true;
- else if (url.substr(0, 6) == "about:")
- return true;
- else if (url.indexOf("firebug-service.js") != -1)
- return true;
- else
- return false;
-};
-
-this.isSystemPage = function(win)
-{
- try
- {
- var doc = win.document;
- if (!doc)
- return false;
-
- // Detect pages for pretty printed XML
- if ((doc.styleSheets.length && doc.styleSheets[0].href
- == "chrome://global/content/xml/XMLPrettyPrint.css")
- || (doc.styleSheets.length > 1 && doc.styleSheets[1].href
- == "chrome://browser/skin/feeds/subscribe.css"))
- return true;
-
- return FBL.isSystemURL(win.location.href);
- }
- catch (exc)
- {
- // Sometimes documents just aren't ready to be manipulated here, but don't let that
- // gum up the works
- ERROR("tabWatcher.isSystemPage document not ready:"+ exc);
- return false;
- }
-};
-
-this.isSystemStyleSheet = function(sheet)
-{
- var href = sheet && sheet.href;
- return href && FBL.isSystemURL(href);
-};
-
-this.getURIHost = function(uri)
-{
- try
- {
- if (uri)
- return uri.host;
- else
- return "";
- }
- catch (exc)
- {
- return "";
- }
-};
-
-this.isLocalURL = function(url)
-{
- if (url.substr(0, 5) == "file:")
- return true;
- else if (url.substr(0, 8) == "wyciwyg:")
- return true;
- else
- return false;
-};
-
-this.isDataURL = function(url)
-{
- return (url && url.substr(0,5) == "data:");
-};
-
-this.getLocalPath = function(url)
-{
- if (this.isLocalURL(url))
- {
- var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler);
- var file = fileHandler.getFileFromURLSpec(url);
- return file.path;
- }
-};
-
-this.getURLFromLocalFile = function(file)
-{
- var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler);
- var URL = fileHandler.getURLSpecFromFile(file);
- return URL;
-};
-
-this.getDataURLForContent = function(content, url)
-{
- // data:text/javascript;fileName=x%2Cy.js;baseLineNumber=10,<the-url-encoded-data>
- var uri = "data:text/html;";
- uri += "fileName="+encodeURIComponent(url)+ ",";
- uri += encodeURIComponent(content);
- return uri;
-},
-
-this.getDomain = function(url)
-{
- var m = /[^:]+:\/{1,3}([^\/]+)/.exec(url);
- return m ? m[1] : "";
-};
-
-this.getURLPath = function(url)
-{
- var m = /[^:]+:\/{1,3}[^\/]+(\/.*?)$/.exec(url);
- return m ? m[1] : "";
-};
-
-this.getPrettyDomain = function(url)
-{
- var m = /[^:]+:\/{1,3}(www\.)?([^\/]+)/.exec(url);
- return m ? m[2] : "";
-};
-
-this.absoluteURL = function(url, baseURL)
-{
- return this.absoluteURLWithDots(url, baseURL).replace("/./", "/", "g");
-};
-
-this.absoluteURLWithDots = function(url, baseURL)
-{
- if (url[0] == "?")
- return baseURL + url;
-
- var reURL = /(([^:]+:)\/{1,2}[^\/]*)(.*?)$/;
- var m = reURL.exec(url);
- if (m)
- return url;
-
- var m = reURL.exec(baseURL);
- if (!m)
- return "";
-
- var head = m[1];
- var tail = m[3];
- if (url.substr(0, 2) == "//")
- return m[2] + url;
- else if (url[0] == "/")
- {
- return head + url;
- }
- else if (tail[tail.length-1] == "/")
- return baseURL + url;
- else
- {
- var parts = tail.split("/");
- return head + parts.slice(0, parts.length-1).join("/") + "/" + url;
- }
-};
-
-this.normalizeURL = function(url) // this gets called a lot, any performance improvement welcome
-{
- if (!url)
- return "";
- // Replace one or more characters that are not forward-slash followed by /.., by space.
- if (url.length < 255) // guard against monsters.
- {
- // Replace one or more characters that are not forward-slash followed by /.., by space.
- url = url.replace(/[^\/]+\/\.\.\//, "", "g");
- // Issue 1496, avoid #
- url = url.replace(/#.*/,"");
- // For some reason, JSDS reports file URLs like "file:/" instead of "file:///", so they
- // don't match up with the URLs we get back from the DOM
- url = url.replace(/file:\/([^\/])/g, "file:///$1");
- if (url.indexOf('chrome:')==0)
- {
- var m = reChromeCase.exec(url); // 1 is package name, 2 is path
- if (m)
- {
- url = "chrome://"+m[1].toLowerCase()+"/"+m[2];
- }
- }
- }
- return url;
-};
-
-this.denormalizeURL = function(url)
-{
- return url.replace(/file:\/\/\//g, "file:/");
-};
-
-this.parseURLParams = function(url)
-{
- var q = url ? url.indexOf("?") : -1;
- if (q == -1)
- return [];
-
- var search = url.substr(q+1);
- var h = search.lastIndexOf("#");
- if (h != -1)
- search = search.substr(0, h);
-
- if (!search)
- return [];
-
- return this.parseURLEncodedText(search);
-};
-
-this.parseURLEncodedText = function(text)
-{
- var maxValueLength = 25000;
-
- var params = [];
-
- // Unescape '+' characters that are used to encode a space.
- // See section 2.2.in RFC 3986: http://www.ietf.org/rfc/rfc3986.txt
- text = text.replace(/\+/g, " ");
-
- var args = text.split("&");
- for (var i = 0; i < args.length; ++i)
- {
- try {
- var parts = args[i].split("=");
- if (parts.length == 2)
- {
- if (parts[1].length > maxValueLength)
- parts[1] = this.$STR("LargeData");
-
- params.push({name: decodeURIComponent(parts[0]), value: decodeURIComponent(parts[1])});
- }
- else
- params.push({name: decodeURIComponent(parts[0]), value: ""});
- }
- catch (e)
- {
- if (FBTrace.DBG_ERRORS)
- {
- FBTrace.sysout("parseURLEncodedText EXCEPTION ", e);
- FBTrace.sysout("parseURLEncodedText EXCEPTION URI", args[i]);
- }
- }
- }
-
- params.sort(function(a, b) { return a.name <= b.name ? -1 : 1; });
-
- return params;
-};
-
-// TODO: xxxpedro lib. why loops in domplate are requiring array in parameters
-// as in response/request headers and get/post parameters in Net module?
-this.parseURLParamsArray = function(url)
-{
- var q = url ? url.indexOf("?") : -1;
- if (q == -1)
- return [];
-
- var search = url.substr(q+1);
- var h = search.lastIndexOf("#");
- if (h != -1)
- search = search.substr(0, h);
-
- if (!search)
- return [];
-
- return this.parseURLEncodedTextArray(search);
-};
-
-this.parseURLEncodedTextArray = function(text)
-{
- var maxValueLength = 25000;
-
- var params = [];
-
- // Unescape '+' characters that are used to encode a space.
- // See section 2.2.in RFC 3986: http://www.ietf.org/rfc/rfc3986.txt
- text = text.replace(/\+/g, " ");
-
- var args = text.split("&");
- for (var i = 0; i < args.length; ++i)
- {
- try {
- var parts = args[i].split("=");
- if (parts.length == 2)
- {
- if (parts[1].length > maxValueLength)
- parts[1] = this.$STR("LargeData");
-
- params.push({name: decodeURIComponent(parts[0]), value: [decodeURIComponent(parts[1])]});
- }
- else
- params.push({name: decodeURIComponent(parts[0]), value: [""]});
- }
- catch (e)
- {
- if (FBTrace.DBG_ERRORS)
- {
- FBTrace.sysout("parseURLEncodedText EXCEPTION ", e);
- FBTrace.sysout("parseURLEncodedText EXCEPTION URI", args[i]);
- }
- }
- }
-
- params.sort(function(a, b) { return a.name <= b.name ? -1 : 1; });
-
- return params;
-};
-
-this.reEncodeURL = function(file, text)
-{
- var lines = text.split("\n");
- var params = this.parseURLEncodedText(lines[lines.length-1]);
-
- var args = [];
- for (var i = 0; i < params.length; ++i)
- args.push(encodeURIComponent(params[i].name)+"="+encodeURIComponent(params[i].value));
-
- var url = file.href;
- url += (url.indexOf("?") == -1 ? "?" : "&") + args.join("&");
-
- return url;
-};
-
-this.getResource = function(aURL)
-{
- try
- {
- var channel=ioService.newChannel(aURL,null,null);
- var input=channel.open();
- return FBL.readFromStream(input);
- }
- catch (e)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("lib.getResource FAILS for "+aURL, e);
- }
-};
-
-this.parseJSONString = function(jsonString, originURL)
-{
- // See if this is a Prototype style *-secure request.
- var regex = new RegExp(/^\/\*-secure-([\s\S]*)\*\/\s*$/);
- var matches = regex.exec(jsonString);
-
- if (matches)
- {
- jsonString = matches[1];
-
- if (jsonString[0] == "\\" && jsonString[1] == "n")
- jsonString = jsonString.substr(2);
-
- if (jsonString[jsonString.length-2] == "\\" && jsonString[jsonString.length-1] == "n")
- jsonString = jsonString.substr(0, jsonString.length-2);
- }
-
- if (jsonString.indexOf("&&&START&&&"))
- {
- regex = new RegExp(/&&&START&&& (.+) &&&END&&&/);
- matches = regex.exec(jsonString);
- if (matches)
- jsonString = matches[1];
- }
-
- // throw on the extra parentheses
- jsonString = "(" + jsonString + ")";
-
- ///var s = Components.utils.Sandbox(originURL);
- var jsonObject = null;
-
- try
- {
- ///jsonObject = Components.utils.evalInSandbox(jsonString, s);
-
- //jsonObject = Firebug.context.eval(jsonString);
- jsonObject = Firebug.context.evaluate(jsonString, null, null, function(){return null;});
- }
- catch(e)
- {
- /***
- if (e.message.indexOf("is not defined"))
- {
- var parts = e.message.split(" ");
- s[parts[0]] = function(str){ return str; };
- try {
- jsonObject = Components.utils.evalInSandbox(jsonString, s);
- } catch(ex) {
- if (FBTrace.DBG_ERRORS || FBTrace.DBG_JSONVIEWER)
- FBTrace.sysout("jsonviewer.parseJSON EXCEPTION", e);
- return null;
- }
- }
- else
- {/**/
- if (FBTrace.DBG_ERRORS || FBTrace.DBG_JSONVIEWER)
- FBTrace.sysout("jsonviewer.parseJSON EXCEPTION", e);
- return null;
- ///}
- }
-
- return jsonObject;
-};
-
-// ************************************************************************************************
-
-this.objectToString = function(object)
-{
- try
- {
- return object+"";
- }
- catch (exc)
- {
- return null;
- }
-};
-
-// ************************************************************************************************
-// Input Caret Position
-
-this.setSelectionRange = function(input, start, length)
-{
- if (input.createTextRange)
- {
- var range = input.createTextRange();
- range.moveStart("character", start);
- range.moveEnd("character", length - input.value.length);
- range.select();
- }
- else if (input.setSelectionRange)
- {
- input.setSelectionRange(start, length);
- input.focus();
- }
-};
-
-// ************************************************************************************************
-// Input Selection Start / Caret Position
-
-this.getInputSelectionStart = function(input)
-{
- if (document.selection)
- {
- var range = input.ownerDocument.selection.createRange();
- var text = range.text;
-
- //console.log("range", range.text);
-
- // if there is a selection, find the start position
- if (text)
- {
- return input.value.indexOf(text);
- }
- // if there is no selection, find the caret position
- else
- {
- range.moveStart("character", -input.value.length);
-
- return range.text.length;
- }
- }
- else if (typeof input.selectionStart != "undefined")
- return input.selectionStart;
-
- return 0;
-};
-
-// ************************************************************************************************
-// Opera Tab Fix
-
-function onOperaTabBlur(e)
-{
- if (this.lastKey == 9)
- this.focus();
-};
-
-function onOperaTabKeyDown(e)
-{
- this.lastKey = e.keyCode;
-};
-
-function onOperaTabFocus(e)
-{
- this.lastKey = null;
-};
-
-this.fixOperaTabKey = function(el)
-{
- el.onfocus = onOperaTabFocus;
- el.onblur = onOperaTabBlur;
- el.onkeydown = onOperaTabKeyDown;
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-this.Property = function(object, name)
-{
- this.object = object;
- this.name = name;
-
- this.getObject = function()
- {
- return object[name];
- };
-};
-
-this.ErrorCopy = function(message)
-{
- this.message = message;
-};
-
-function EventCopy(event)
-{
- // Because event objects are destroyed arbitrarily by Gecko, we must make a copy of them to
- // represent them long term in the inspector.
- for (var name in event)
- {
- try {
- this[name] = event[name];
- } catch (exc) { }
- }
-}
-
-this.EventCopy = EventCopy;
-
-
-// ************************************************************************************************
-// Type Checking
-
-var toString = Object.prototype.toString;
-var reFunction = /^\s*function(\s+[\w_$][\w\d_$]*)?\s*\(/;
-
-this.isArray = function(object) {
- return toString.call(object) === '[object Array]';
-};
-
-this.isFunction = function(object) {
- if (!object) return false;
-
- try
- {
- // FIXME: xxxpedro this is failing in IE for the global "external" object
- return toString.call(object) === "[object Function]" ||
- this.isIE && typeof object != "string" && reFunction.test(""+object);
- }
- catch (E)
- {
- FBTrace.sysout("Lib.isFunction() failed for ", object);
- return false;
- }
-};
-
-
-// ************************************************************************************************
-// Instance Checking
-
-this.instanceOf = function(object, className)
-{
- if (!object || typeof object != "object")
- return false;
-
- // Try to use the native instanceof operator. We can only use it when we know
- // exactly the window where the object is located at
- if (object.ownerDocument)
- {
- // find the correct window of the object
- var win = object.ownerDocument.defaultView || object.ownerDocument.parentWindow;
-
- // if the class is accessible in the window, uses the native instanceof operator
- // if the instanceof evaluates to "true" we can assume it is a instance, but if it
- // evaluates to "false" we must continue with the duck type detection below because
- // the native object may be extended, thus breaking the instanceof result
- // See Issue 3524: Firebug Lite Style Panel doesn't work if the native Element is extended
- if (className in win && object instanceof win[className])
- return true;
- }
- // If the object doesn't have the ownerDocument property, we'll try to look at
- // the current context's window
- else
- {
- // TODO: xxxpedro context
- // Since we're not using yet a Firebug.context, we'll just use the top window
- // (browser) as a reference
- var win = Firebug.browser.window;
- if (className in win)
- return object instanceof win[className];
- }
-
- // get the duck type model from the cache
- var cache = instanceCheckMap[className];
- if (!cache)
- return false;
-
- // starts the hacky duck type detection
- for(var n in cache)
- {
- var obj = cache[n];
- var type = typeof obj;
- obj = type == "object" ? obj : [obj];
-
- for(var name in obj)
- {
- // avoid problems with extended native objects
- // See Issue 3524: Firebug Lite Style Panel doesn't work if the native Element is extended
- if (!obj.hasOwnProperty(name))
- continue;
-
- var value = obj[name];
-
- if( n == "property" && !(value in object) ||
- n == "method" && !this.isFunction(object[value]) ||
- n == "value" && (""+object[name]).toLowerCase() != (""+value).toLowerCase() )
- return false;
- }
- }
-
- return true;
-};
-
-var instanceCheckMap =
-{
- // DuckTypeCheck:
- // {
- // property: ["window", "document"],
- // method: "setTimeout",
- // value: {nodeType: 1}
- // },
-
- Window:
- {
- property: ["window", "document"],
- method: "setTimeout"
- },
-
- Document:
- {
- property: ["body", "cookie"],
- method: "getElementById"
- },
-
- Node:
- {
- property: "ownerDocument",
- method: "appendChild"
- },
-
- Element:
- {
- property: "tagName",
- value: {nodeType: 1}
- },
-
- Location:
- {
- property: ["hostname", "protocol"],
- method: "assign"
- },
-
- HTMLImageElement:
- {
- property: "useMap",
- value:
- {
- nodeType: 1,
- tagName: "img"
- }
- },
-
- HTMLAnchorElement:
- {
- property: "hreflang",
- value:
- {
- nodeType: 1,
- tagName: "a"
- }
- },
-
- HTMLInputElement:
- {
- property: "form",
- value:
- {
- nodeType: 1,
- tagName: "input"
- }
- },
-
- HTMLButtonElement:
- {
- // ?
- },
-
- HTMLFormElement:
- {
- method: "submit",
- value:
- {
- nodeType: 1,
- tagName: "form"
- }
- },
-
- HTMLBodyElement:
- {
-
- },
-
- HTMLHtmlElement:
- {
-
- },
-
- CSSStyleRule:
- {
- property: ["selectorText", "style"]
- }
-
-};
-
-
-// ************************************************************************************************
-// DOM Constants
-
-/*
-
-Problems:
-
- - IE does not have window.Node, window.Element, etc
- - for (var name in Node.prototype) return nothing on FF
-
-*/
-
-
-var domMemberMap2 = {};
-
-var domMemberMap2Sandbox = null;
-
-var getDomMemberMap2 = function(name)
-{
- if (!domMemberMap2Sandbox)
- {
- var doc = Firebug.chrome.document;
- var frame = doc.createElement("iframe");
-
- frame.id = "FirebugSandbox";
- frame.style.display = "none";
- frame.src = "about:blank";
-
- doc.body.appendChild(frame);
-
- domMemberMap2Sandbox = frame.window || frame.contentWindow;
- }
-
- var props = [];
-
- //var object = domMemberMap2Sandbox[name];
- //object = object.prototype || object;
-
- var object = null;
-
- if (name == "Window")
- object = domMemberMap2Sandbox.window;
-
- else if (name == "Document")
- object = domMemberMap2Sandbox.document;
-
- else if (name == "HTMLScriptElement")
- object = domMemberMap2Sandbox.document.createElement("script");
-
- else if (name == "HTMLAnchorElement")
- object = domMemberMap2Sandbox.document.createElement("a");
-
- else if (name.indexOf("Element") != -1)
- {
- object = domMemberMap2Sandbox.document.createElement("div");
- }
-
- if (object)
- {
- //object = object.prototype || object;
-
- //props = 'addEventListener,document,location,navigator,window'.split(',');
-
- for (var n in object)
- props.push(n);
- }
- /**/
-
- return props;
- return extendArray(props, domMemberMap[name]);
-};
-
-// xxxpedro experimental get DOM members
-this.getDOMMembers = function(object)
-{
- if (!domMemberCache)
- {
- FBL.domMemberCache = domMemberCache = {};
-
- for (var name in domMemberMap)
- {
- var builtins = getDomMemberMap2(name);
- var cache = domMemberCache[name] = {};
-
- /*
- if (name.indexOf("Element") != -1)
- {
- this.append(cache, this.getDOMMembers("Node"));
- this.append(cache, this.getDOMMembers("Element"));
- }
- /**/
-
- for (var i = 0; i < builtins.length; ++i)
- cache[builtins[i]] = i;
- }
- }
-
- try
- {
- if (this.instanceOf(object, "Window"))
- { return domMemberCache.Window; }
- else if (this.instanceOf(object, "Document") || this.instanceOf(object, "XMLDocument"))
- { return domMemberCache.Document; }
- else if (this.instanceOf(object, "Location"))
- { return domMemberCache.Location; }
- else if (this.instanceOf(object, "HTMLImageElement"))
- { return domMemberCache.HTMLImageElement; }
- else if (this.instanceOf(object, "HTMLAnchorElement"))
- { return domMemberCache.HTMLAnchorElement; }
- else if (this.instanceOf(object, "HTMLInputElement"))
- { return domMemberCache.HTMLInputElement; }
- else if (this.instanceOf(object, "HTMLButtonElement"))
- { return domMemberCache.HTMLButtonElement; }
- else if (this.instanceOf(object, "HTMLFormElement"))
- { return domMemberCache.HTMLFormElement; }
- else if (this.instanceOf(object, "HTMLBodyElement"))
- { return domMemberCache.HTMLBodyElement; }
- else if (this.instanceOf(object, "HTMLHtmlElement"))
- { return domMemberCache.HTMLHtmlElement; }
- else if (this.instanceOf(object, "HTMLScriptElement"))
- { return domMemberCache.HTMLScriptElement; }
- else if (this.instanceOf(object, "HTMLTableElement"))
- { return domMemberCache.HTMLTableElement; }
- else if (this.instanceOf(object, "HTMLTableRowElement"))
- { return domMemberCache.HTMLTableRowElement; }
- else if (this.instanceOf(object, "HTMLTableCellElement"))
- { return domMemberCache.HTMLTableCellElement; }
- else if (this.instanceOf(object, "HTMLIFrameElement"))
- { return domMemberCache.HTMLIFrameElement; }
- else if (this.instanceOf(object, "SVGSVGElement"))
- { return domMemberCache.SVGSVGElement; }
- else if (this.instanceOf(object, "SVGElement"))
- { return domMemberCache.SVGElement; }
- else if (this.instanceOf(object, "Element"))
- { return domMemberCache.Element; }
- else if (this.instanceOf(object, "Text") || this.instanceOf(object, "CDATASection"))
- { return domMemberCache.Text; }
- else if (this.instanceOf(object, "Attr"))
- { return domMemberCache.Attr; }
- else if (this.instanceOf(object, "Node"))
- { return domMemberCache.Node; }
- else if (this.instanceOf(object, "Event") || this.instanceOf(object, "EventCopy"))
- { return domMemberCache.Event; }
- else
- return {};
- }
- catch(E)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("lib.getDOMMembers FAILED ", E);
-
- return {};
- }
-};
-
-
-/*
-this.getDOMMembers = function(object)
-{
- if (!domMemberCache)
- {
- domMemberCache = {};
-
- for (var name in domMemberMap)
- {
- var builtins = domMemberMap[name];
- var cache = domMemberCache[name] = {};
-
- for (var i = 0; i < builtins.length; ++i)
- cache[builtins[i]] = i;
- }
- }
-
- try
- {
- if (this.instanceOf(object, "Window"))
- { return domMemberCache.Window; }
- else if (object instanceof Document || object instanceof XMLDocument)
- { return domMemberCache.Document; }
- else if (object instanceof Location)
- { return domMemberCache.Location; }
- else if (object instanceof HTMLImageElement)
- { return domMemberCache.HTMLImageElement; }
- else if (object instanceof HTMLAnchorElement)
- { return domMemberCache.HTMLAnchorElement; }
- else if (object instanceof HTMLInputElement)
- { return domMemberCache.HTMLInputElement; }
- else if (object instanceof HTMLButtonElement)
- { return domMemberCache.HTMLButtonElement; }
- else if (object instanceof HTMLFormElement)
- { return domMemberCache.HTMLFormElement; }
- else if (object instanceof HTMLBodyElement)
- { return domMemberCache.HTMLBodyElement; }
- else if (object instanceof HTMLHtmlElement)
- { return domMemberCache.HTMLHtmlElement; }
- else if (object instanceof HTMLScriptElement)
- { return domMemberCache.HTMLScriptElement; }
- else if (object instanceof HTMLTableElement)
- { return domMemberCache.HTMLTableElement; }
- else if (object instanceof HTMLTableRowElement)
- { return domMemberCache.HTMLTableRowElement; }
- else if (object instanceof HTMLTableCellElement)
- { return domMemberCache.HTMLTableCellElement; }
- else if (object instanceof HTMLIFrameElement)
- { return domMemberCache.HTMLIFrameElement; }
- else if (object instanceof SVGSVGElement)
- { return domMemberCache.SVGSVGElement; }
- else if (object instanceof SVGElement)
- { return domMemberCache.SVGElement; }
- else if (object instanceof Element)
- { return domMemberCache.Element; }
- else if (object instanceof Text || object instanceof CDATASection)
- { return domMemberCache.Text; }
- else if (object instanceof Attr)
- { return domMemberCache.Attr; }
- else if (object instanceof Node)
- { return domMemberCache.Node; }
- else if (object instanceof Event || object instanceof EventCopy)
- { return domMemberCache.Event; }
- else
- return {};
- }
- catch(E)
- {
- return {};
- }
-};
-/**/
-
-this.isDOMMember = function(object, propName)
-{
- var members = this.getDOMMembers(object);
- return members && propName in members;
-};
-
-var domMemberCache = null;
-var domMemberMap = {};
-
-domMemberMap.Window =
-[
- "document",
- "frameElement",
-
- "innerWidth",
- "innerHeight",
- "outerWidth",
- "outerHeight",
- "screenX",
- "screenY",
- "pageXOffset",
- "pageYOffset",
- "scrollX",
- "scrollY",
- "scrollMaxX",
- "scrollMaxY",
-
- "status",
- "defaultStatus",
-
- "parent",
- "opener",
- "top",
- "window",
- "content",
- "self",
-
- "location",
- "history",
- "frames",
- "navigator",
- "screen",
- "menubar",
- "toolbar",
- "locationbar",
- "personalbar",
- "statusbar",
- "directories",
- "scrollbars",
- "fullScreen",
- "netscape",
- "java",
- "console",
- "Components",
- "controllers",
- "closed",
- "crypto",
- "pkcs11",
-
- "name",
- "property",
- "length",
-
- "sessionStorage",
- "globalStorage",
-
- "setTimeout",
- "setInterval",
- "clearTimeout",
- "clearInterval",
- "addEventListener",
- "removeEventListener",
- "dispatchEvent",
- "getComputedStyle",
- "captureEvents",
- "releaseEvents",
- "routeEvent",
- "enableExternalCapture",
- "disableExternalCapture",
- "moveTo",
- "moveBy",
- "resizeTo",
- "resizeBy",
- "scroll",
- "scrollTo",
- "scrollBy",
- "scrollByLines",
- "scrollByPages",
- "sizeToContent",
- "setResizable",
- "getSelection",
- "open",
- "openDialog",
- "close",
- "alert",
- "confirm",
- "prompt",
- "dump",
- "focus",
- "blur",
- "find",
- "back",
- "forward",
- "home",
- "stop",
- "print",
- "atob",
- "btoa",
- "updateCommands",
- "XPCNativeWrapper",
- "GeckoActiveXObject",
- "applicationCache" // FF3
-];
-
-domMemberMap.Location =
-[
- "href",
- "protocol",
- "host",
- "hostname",
- "port",
- "pathname",
- "search",
- "hash",
-
- "assign",
- "reload",
- "replace"
-];
-
-domMemberMap.Node =
-[
- "id",
- "className",
-
- "nodeType",
- "tagName",
- "nodeName",
- "localName",
- "prefix",
- "namespaceURI",
- "nodeValue",
-
- "ownerDocument",
- "parentNode",
- "offsetParent",
- "nextSibling",
- "previousSibling",
- "firstChild",
- "lastChild",
- "childNodes",
- "attributes",
-
- "dir",
- "baseURI",
- "textContent",
- "innerHTML",
-
- "addEventListener",
- "removeEventListener",
- "dispatchEvent",
- "cloneNode",
- "appendChild",
- "insertBefore",
- "replaceChild",
- "removeChild",
- "compareDocumentPosition",
- "hasAttributes",
- "hasChildNodes",
- "lookupNamespaceURI",
- "lookupPrefix",
- "normalize",
- "isDefaultNamespace",
- "isEqualNode",
- "isSameNode",
- "isSupported",
- "getFeature",
- "getUserData",
- "setUserData"
-];
-
-domMemberMap.Document = extendArray(domMemberMap.Node,
-[
- "documentElement",
- "body",
- "title",
- "location",
- "referrer",
- "cookie",
- "contentType",
- "lastModified",
- "characterSet",
- "inputEncoding",
- "xmlEncoding",
- "xmlStandalone",
- "xmlVersion",
- "strictErrorChecking",
- "documentURI",
- "URL",
-
- "defaultView",
- "doctype",
- "implementation",
- "styleSheets",
- "images",
- "links",
- "forms",
- "anchors",
- "embeds",
- "plugins",
- "applets",
-
- "width",
- "height",
-
- "designMode",
- "compatMode",
- "async",
- "preferredStylesheetSet",
-
- "alinkColor",
- "linkColor",
- "vlinkColor",
- "bgColor",
- "fgColor",
- "domain",
-
- "addEventListener",
- "removeEventListener",
- "dispatchEvent",
- "captureEvents",
- "releaseEvents",
- "routeEvent",
- "clear",
- "open",
- "close",
- "execCommand",
- "execCommandShowHelp",
- "getElementsByName",
- "getSelection",
- "queryCommandEnabled",
- "queryCommandIndeterm",
- "queryCommandState",
- "queryCommandSupported",
- "queryCommandText",
- "queryCommandValue",
- "write",
- "writeln",
- "adoptNode",
- "appendChild",
- "removeChild",
- "renameNode",
- "cloneNode",
- "compareDocumentPosition",
- "createAttribute",
- "createAttributeNS",
- "createCDATASection",
- "createComment",
- "createDocumentFragment",
- "createElement",
- "createElementNS",
- "createEntityReference",
- "createEvent",
- "createExpression",
- "createNSResolver",
- "createNodeIterator",
- "createProcessingInstruction",
- "createRange",
- "createTextNode",
- "createTreeWalker",
- "domConfig",
- "evaluate",
- "evaluateFIXptr",
- "evaluateXPointer",
- "getAnonymousElementByAttribute",
- "getAnonymousNodes",
- "addBinding",
- "removeBinding",
- "getBindingParent",
- "getBoxObjectFor",
- "setBoxObjectFor",
- "getElementById",
- "getElementsByTagName",
- "getElementsByTagNameNS",
- "hasAttributes",
- "hasChildNodes",
- "importNode",
- "insertBefore",
- "isDefaultNamespace",
- "isEqualNode",
- "isSameNode",
- "isSupported",
- "load",
- "loadBindingDocument",
- "lookupNamespaceURI",
- "lookupPrefix",
- "normalize",
- "normalizeDocument",
- "getFeature",
- "getUserData",
- "setUserData"
-]);
-
-domMemberMap.Element = extendArray(domMemberMap.Node,
-[
- "clientWidth",
- "clientHeight",
- "offsetLeft",
- "offsetTop",
- "offsetWidth",
- "offsetHeight",
- "scrollLeft",
- "scrollTop",
- "scrollWidth",
- "scrollHeight",
-
- "style",
-
- "tabIndex",
- "title",
- "lang",
- "align",
- "spellcheck",
-
- "addEventListener",
- "removeEventListener",
- "dispatchEvent",
- "focus",
- "blur",
- "cloneNode",
- "appendChild",
- "insertBefore",
- "replaceChild",
- "removeChild",
- "compareDocumentPosition",
- "getElementsByTagName",
- "getElementsByTagNameNS",
- "getAttribute",
- "getAttributeNS",
- "getAttributeNode",
- "getAttributeNodeNS",
- "setAttribute",
- "setAttributeNS",
- "setAttributeNode",
- "setAttributeNodeNS",
- "removeAttribute",
- "removeAttributeNS",
- "removeAttributeNode",
- "hasAttribute",
- "hasAttributeNS",
- "hasAttributes",
- "hasChildNodes",
- "lookupNamespaceURI",
- "lookupPrefix",
- "normalize",
- "isDefaultNamespace",
- "isEqualNode",
- "isSameNode",
- "isSupported",
- "getFeature",
- "getUserData",
- "setUserData"
-]);
-
-domMemberMap.SVGElement = extendArray(domMemberMap.Element,
-[
- "x",
- "y",
- "width",
- "height",
- "rx",
- "ry",
- "transform",
- "href",
-
- "ownerSVGElement",
- "viewportElement",
- "farthestViewportElement",
- "nearestViewportElement",
-
- "getBBox",
- "getCTM",
- "getScreenCTM",
- "getTransformToElement",
- "getPresentationAttribute",
- "preserveAspectRatio"
-]);
-
-domMemberMap.SVGSVGElement = extendArray(domMemberMap.Element,
-[
- "x",
- "y",
- "width",
- "height",
- "rx",
- "ry",
- "transform",
-
- "viewBox",
- "viewport",
- "currentView",
- "useCurrentView",
- "pixelUnitToMillimeterX",
- "pixelUnitToMillimeterY",
- "screenPixelToMillimeterX",
- "screenPixelToMillimeterY",
- "currentScale",
- "currentTranslate",
- "zoomAndPan",
-
- "ownerSVGElement",
- "viewportElement",
- "farthestViewportElement",
- "nearestViewportElement",
- "contentScriptType",
- "contentStyleType",
-
- "getBBox",
- "getCTM",
- "getScreenCTM",
- "getTransformToElement",
- "getEnclosureList",
- "getIntersectionList",
- "getViewboxToViewportTransform",
- "getPresentationAttribute",
- "getElementById",
- "checkEnclosure",
- "checkIntersection",
- "createSVGAngle",
- "createSVGLength",
- "createSVGMatrix",
- "createSVGNumber",
- "createSVGPoint",
- "createSVGRect",
- "createSVGString",
- "createSVGTransform",
- "createSVGTransformFromMatrix",
- "deSelectAll",
- "preserveAspectRatio",
- "forceRedraw",
- "suspendRedraw",
- "unsuspendRedraw",
- "unsuspendRedrawAll",
- "getCurrentTime",
- "setCurrentTime",
- "animationsPaused",
- "pauseAnimations",
- "unpauseAnimations"
-]);
-
-domMemberMap.HTMLImageElement = extendArray(domMemberMap.Element,
-[
- "src",
- "naturalWidth",
- "naturalHeight",
- "width",
- "height",
- "x",
- "y",
- "name",
- "alt",
- "longDesc",
- "lowsrc",
- "border",
- "complete",
- "hspace",
- "vspace",
- "isMap",
- "useMap"
-]);
-
-domMemberMap.HTMLAnchorElement = extendArray(domMemberMap.Element,
-[
- "name",
- "target",
- "accessKey",
- "href",
- "protocol",
- "host",
- "hostname",
- "port",
- "pathname",
- "search",
- "hash",
- "hreflang",
- "coords",
- "shape",
- "text",
- "type",
- "rel",
- "rev",
- "charset"
-]);
-
-domMemberMap.HTMLIFrameElement = extendArray(domMemberMap.Element,
-[
- "contentDocument",
- "contentWindow",
- "frameBorder",
- "height",
- "longDesc",
- "marginHeight",
- "marginWidth",
- "name",
- "scrolling",
- "src",
- "width"
-]);
-
-domMemberMap.HTMLTableElement = extendArray(domMemberMap.Element,
-[
- "bgColor",
- "border",
- "caption",
- "cellPadding",
- "cellSpacing",
- "frame",
- "rows",
- "rules",
- "summary",
- "tBodies",
- "tFoot",
- "tHead",
- "width",
-
- "createCaption",
- "createTFoot",
- "createTHead",
- "deleteCaption",
- "deleteRow",
- "deleteTFoot",
- "deleteTHead",
- "insertRow"
-]);
-
-domMemberMap.HTMLTableRowElement = extendArray(domMemberMap.Element,
-[
- "bgColor",
- "cells",
- "ch",
- "chOff",
- "rowIndex",
- "sectionRowIndex",
- "vAlign",
-
- "deleteCell",
- "insertCell"
-]);
-
-domMemberMap.HTMLTableCellElement = extendArray(domMemberMap.Element,
-[
- "abbr",
- "axis",
- "bgColor",
- "cellIndex",
- "ch",
- "chOff",
- "colSpan",
- "headers",
- "height",
- "noWrap",
- "rowSpan",
- "scope",
- "vAlign",
- "width"
-
-]);
-
-domMemberMap.HTMLScriptElement = extendArray(domMemberMap.Element,
-[
- "src"
-]);
-
-domMemberMap.HTMLButtonElement = extendArray(domMemberMap.Element,
-[
- "accessKey",
- "disabled",
- "form",
- "name",
- "type",
- "value",
-
- "click"
-]);
-
-domMemberMap.HTMLInputElement = extendArray(domMemberMap.Element,
-[
- "type",
- "value",
- "checked",
- "accept",
- "accessKey",
- "alt",
- "controllers",
- "defaultChecked",
- "defaultValue",
- "disabled",
- "form",
- "maxLength",
- "name",
- "readOnly",
- "selectionEnd",
- "selectionStart",
- "size",
- "src",
- "textLength",
- "useMap",
-
- "click",
- "select",
- "setSelectionRange"
-]);
-
-domMemberMap.HTMLFormElement = extendArray(domMemberMap.Element,
-[
- "acceptCharset",
- "action",
- "author",
- "elements",
- "encoding",
- "enctype",
- "entry_id",
- "length",
- "method",
- "name",
- "post",
- "target",
- "text",
- "url",
-
- "reset",
- "submit"
-]);
-
-domMemberMap.HTMLBodyElement = extendArray(domMemberMap.Element,
-[
- "aLink",
- "background",
- "bgColor",
- "link",
- "text",
- "vLink"
-]);
-
-domMemberMap.HTMLHtmlElement = extendArray(domMemberMap.Element,
-[
- "version"
-]);
-
-domMemberMap.Text = extendArray(domMemberMap.Node,
-[
- "data",
- "length",
-
- "appendData",
- "deleteData",
- "insertData",
- "replaceData",
- "splitText",
- "substringData"
-]);
-
-domMemberMap.Attr = extendArray(domMemberMap.Node,
-[
- "name",
- "value",
- "specified",
- "ownerElement"
-]);
-
-domMemberMap.Event =
-[
- "type",
- "target",
- "currentTarget",
- "originalTarget",
- "explicitOriginalTarget",
- "relatedTarget",
- "rangeParent",
- "rangeOffset",
- "view",
-
- "keyCode",
- "charCode",
- "screenX",
- "screenY",
- "clientX",
- "clientY",
- "layerX",
- "layerY",
- "pageX",
- "pageY",
-
- "detail",
- "button",
- "which",
- "ctrlKey",
- "shiftKey",
- "altKey",
- "metaKey",
-
- "eventPhase",
- "timeStamp",
- "bubbles",
- "cancelable",
- "cancelBubble",
-
- "isTrusted",
- "isChar",
-
- "getPreventDefault",
- "initEvent",
- "initMouseEvent",
- "initKeyEvent",
- "initUIEvent",
- "preventBubble",
- "preventCapture",
- "preventDefault",
- "stopPropagation"
-];
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-this.domConstantMap =
-{
- "ELEMENT_NODE": 1,
- "ATTRIBUTE_NODE": 1,
- "TEXT_NODE": 1,
- "CDATA_SECTION_NODE": 1,
- "ENTITY_REFERENCE_NODE": 1,
- "ENTITY_NODE": 1,
- "PROCESSING_INSTRUCTION_NODE": 1,
- "COMMENT_NODE": 1,
- "DOCUMENT_NODE": 1,
- "DOCUMENT_TYPE_NODE": 1,
- "DOCUMENT_FRAGMENT_NODE": 1,
- "NOTATION_NODE": 1,
-
- "DOCUMENT_POSITION_DISCONNECTED": 1,
- "DOCUMENT_POSITION_PRECEDING": 1,
- "DOCUMENT_POSITION_FOLLOWING": 1,
- "DOCUMENT_POSITION_CONTAINS": 1,
- "DOCUMENT_POSITION_CONTAINED_BY": 1,
- "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC": 1,
-
- "UNKNOWN_RULE": 1,
- "STYLE_RULE": 1,
- "CHARSET_RULE": 1,
- "IMPORT_RULE": 1,
- "MEDIA_RULE": 1,
- "FONT_FACE_RULE": 1,
- "PAGE_RULE": 1,
-
- "CAPTURING_PHASE": 1,
- "AT_TARGET": 1,
- "BUBBLING_PHASE": 1,
-
- "SCROLL_PAGE_UP": 1,
- "SCROLL_PAGE_DOWN": 1,
-
- "MOUSEUP": 1,
- "MOUSEDOWN": 1,
- "MOUSEOVER": 1,
- "MOUSEOUT": 1,
- "MOUSEMOVE": 1,
- "MOUSEDRAG": 1,
- "CLICK": 1,
- "DBLCLICK": 1,
- "KEYDOWN": 1,
- "KEYUP": 1,
- "KEYPRESS": 1,
- "DRAGDROP": 1,
- "FOCUS": 1,
- "BLUR": 1,
- "SELECT": 1,
- "CHANGE": 1,
- "RESET": 1,
- "SUBMIT": 1,
- "SCROLL": 1,
- "LOAD": 1,
- "UNLOAD": 1,
- "XFER_DONE": 1,
- "ABORT": 1,
- "ERROR": 1,
- "LOCATE": 1,
- "MOVE": 1,
- "RESIZE": 1,
- "FORWARD": 1,
- "HELP": 1,
- "BACK": 1,
- "TEXT": 1,
-
- "ALT_MASK": 1,
- "CONTROL_MASK": 1,
- "SHIFT_MASK": 1,
- "META_MASK": 1,
-
- "DOM_VK_TAB": 1,
- "DOM_VK_PAGE_UP": 1,
- "DOM_VK_PAGE_DOWN": 1,
- "DOM_VK_UP": 1,
- "DOM_VK_DOWN": 1,
- "DOM_VK_LEFT": 1,
- "DOM_VK_RIGHT": 1,
- "DOM_VK_CANCEL": 1,
- "DOM_VK_HELP": 1,
- "DOM_VK_BACK_SPACE": 1,
- "DOM_VK_CLEAR": 1,
- "DOM_VK_RETURN": 1,
- "DOM_VK_ENTER": 1,
- "DOM_VK_SHIFT": 1,
- "DOM_VK_CONTROL": 1,
- "DOM_VK_ALT": 1,
- "DOM_VK_PAUSE": 1,
- "DOM_VK_CAPS_LOCK": 1,
- "DOM_VK_ESCAPE": 1,
- "DOM_VK_SPACE": 1,
- "DOM_VK_END": 1,
- "DOM_VK_HOME": 1,
- "DOM_VK_PRINTSCREEN": 1,
- "DOM_VK_INSERT": 1,
- "DOM_VK_DELETE": 1,
- "DOM_VK_0": 1,
- "DOM_VK_1": 1,
- "DOM_VK_2": 1,
- "DOM_VK_3": 1,
- "DOM_VK_4": 1,
- "DOM_VK_5": 1,
- "DOM_VK_6": 1,
- "DOM_VK_7": 1,
- "DOM_VK_8": 1,
- "DOM_VK_9": 1,
- "DOM_VK_SEMICOLON": 1,
- "DOM_VK_EQUALS": 1,
- "DOM_VK_A": 1,
- "DOM_VK_B": 1,
- "DOM_VK_C": 1,
- "DOM_VK_D": 1,
- "DOM_VK_E": 1,
- "DOM_VK_F": 1,
- "DOM_VK_G": 1,
- "DOM_VK_H": 1,
- "DOM_VK_I": 1,
- "DOM_VK_J": 1,
- "DOM_VK_K": 1,
- "DOM_VK_L": 1,
- "DOM_VK_M": 1,
- "DOM_VK_N": 1,
- "DOM_VK_O": 1,
- "DOM_VK_P": 1,
- "DOM_VK_Q": 1,
- "DOM_VK_R": 1,
- "DOM_VK_S": 1,
- "DOM_VK_T": 1,
- "DOM_VK_U": 1,
- "DOM_VK_V": 1,
- "DOM_VK_W": 1,
- "DOM_VK_X": 1,
- "DOM_VK_Y": 1,
- "DOM_VK_Z": 1,
- "DOM_VK_CONTEXT_MENU": 1,
- "DOM_VK_NUMPAD0": 1,
- "DOM_VK_NUMPAD1": 1,
- "DOM_VK_NUMPAD2": 1,
- "DOM_VK_NUMPAD3": 1,
- "DOM_VK_NUMPAD4": 1,
- "DOM_VK_NUMPAD5": 1,
- "DOM_VK_NUMPAD6": 1,
- "DOM_VK_NUMPAD7": 1,
- "DOM_VK_NUMPAD8": 1,
- "DOM_VK_NUMPAD9": 1,
- "DOM_VK_MULTIPLY": 1,
- "DOM_VK_ADD": 1,
- "DOM_VK_SEPARATOR": 1,
- "DOM_VK_SUBTRACT": 1,
- "DOM_VK_DECIMAL": 1,
- "DOM_VK_DIVIDE": 1,
- "DOM_VK_F1": 1,
- "DOM_VK_F2": 1,
- "DOM_VK_F3": 1,
- "DOM_VK_F4": 1,
- "DOM_VK_F5": 1,
- "DOM_VK_F6": 1,
- "DOM_VK_F7": 1,
- "DOM_VK_F8": 1,
- "DOM_VK_F9": 1,
- "DOM_VK_F10": 1,
- "DOM_VK_F11": 1,
- "DOM_VK_F12": 1,
- "DOM_VK_F13": 1,
- "DOM_VK_F14": 1,
- "DOM_VK_F15": 1,
- "DOM_VK_F16": 1,
- "DOM_VK_F17": 1,
- "DOM_VK_F18": 1,
- "DOM_VK_F19": 1,
- "DOM_VK_F20": 1,
- "DOM_VK_F21": 1,
- "DOM_VK_F22": 1,
- "DOM_VK_F23": 1,
- "DOM_VK_F24": 1,
- "DOM_VK_NUM_LOCK": 1,
- "DOM_VK_SCROLL_LOCK": 1,
- "DOM_VK_COMMA": 1,
- "DOM_VK_PERIOD": 1,
- "DOM_VK_SLASH": 1,
- "DOM_VK_BACK_QUOTE": 1,
- "DOM_VK_OPEN_BRACKET": 1,
- "DOM_VK_BACK_SLASH": 1,
- "DOM_VK_CLOSE_BRACKET": 1,
- "DOM_VK_QUOTE": 1,
- "DOM_VK_META": 1,
-
- "SVG_ZOOMANDPAN_DISABLE": 1,
- "SVG_ZOOMANDPAN_MAGNIFY": 1,
- "SVG_ZOOMANDPAN_UNKNOWN": 1
-};
-
-this.cssInfo =
-{
- "background": ["bgRepeat", "bgAttachment", "bgPosition", "color", "systemColor", "none"],
- "background-attachment": ["bgAttachment"],
- "background-color": ["color", "systemColor"],
- "background-image": ["none"],
- "background-position": ["bgPosition"],
- "background-repeat": ["bgRepeat"],
-
- "border": ["borderStyle", "thickness", "color", "systemColor", "none"],
- "border-top": ["borderStyle", "borderCollapse", "color", "systemColor", "none"],
- "border-right": ["borderStyle", "borderCollapse", "color", "systemColor", "none"],
- "border-bottom": ["borderStyle", "borderCollapse", "color", "systemColor", "none"],
- "border-left": ["borderStyle", "borderCollapse", "color", "systemColor", "none"],
- "border-collapse": ["borderCollapse"],
- "border-color": ["color", "systemColor"],
- "border-top-color": ["color", "systemColor"],
- "border-right-color": ["color", "systemColor"],
- "border-bottom-color": ["color", "systemColor"],
- "border-left-color": ["color", "systemColor"],
- "border-spacing": [],
- "border-style": ["borderStyle"],
- "border-top-style": ["borderStyle"],
- "border-right-style": ["borderStyle"],
- "border-bottom-style": ["borderStyle"],
- "border-left-style": ["borderStyle"],
- "border-width": ["thickness"],
- "border-top-width": ["thickness"],
- "border-right-width": ["thickness"],
- "border-bottom-width": ["thickness"],
- "border-left-width": ["thickness"],
-
- "bottom": ["auto"],
- "caption-side": ["captionSide"],
- "clear": ["clear", "none"],
- "clip": ["auto"],
- "color": ["color", "systemColor"],
- "content": ["content"],
- "counter-increment": ["none"],
- "counter-reset": ["none"],
- "cursor": ["cursor", "none"],
- "direction": ["direction"],
- "display": ["display", "none"],
- "empty-cells": [],
- "float": ["float", "none"],
- "font": ["fontStyle", "fontVariant", "fontWeight", "fontFamily"],
-
- "font-family": ["fontFamily"],
- "font-size": ["fontSize"],
- "font-size-adjust": [],
- "font-stretch": [],
- "font-style": ["fontStyle"],
- "font-variant": ["fontVariant"],
- "font-weight": ["fontWeight"],
-
- "height": ["auto"],
- "left": ["auto"],
- "letter-spacing": [],
- "line-height": [],
-
- "list-style": ["listStyleType", "listStylePosition", "none"],
- "list-style-image": ["none"],
- "list-style-position": ["listStylePosition"],
- "list-style-type": ["listStyleType", "none"],
-
- "margin": [],
- "margin-top": [],
- "margin-right": [],
- "margin-bottom": [],
- "margin-left": [],
-
- "marker-offset": ["auto"],
- "min-height": ["none"],
- "max-height": ["none"],
- "min-width": ["none"],
- "max-width": ["none"],
-
- "outline": ["borderStyle", "color", "systemColor", "none"],
- "outline-color": ["color", "systemColor"],
- "outline-style": ["borderStyle"],
- "outline-width": [],
-
- "overflow": ["overflow", "auto"],
- "overflow-x": ["overflow", "auto"],
- "overflow-y": ["overflow", "auto"],
-
- "padding": [],
- "padding-top": [],
- "padding-right": [],
- "padding-bottom": [],
- "padding-left": [],
-
- "position": ["position"],
- "quotes": ["none"],
- "right": ["auto"],
- "table-layout": ["tableLayout", "auto"],
- "text-align": ["textAlign"],
- "text-decoration": ["textDecoration", "none"],
- "text-indent": [],
- "text-shadow": [],
- "text-transform": ["textTransform", "none"],
- "top": ["auto"],
- "unicode-bidi": [],
- "vertical-align": ["verticalAlign"],
- "white-space": ["whiteSpace"],
- "width": ["auto"],
- "word-spacing": [],
- "z-index": [],
-
- "-moz-appearance": ["mozAppearance"],
- "-moz-border-radius": [],
- "-moz-border-radius-bottomleft": [],
- "-moz-border-radius-bottomright": [],
- "-moz-border-radius-topleft": [],
- "-moz-border-radius-topright": [],
- "-moz-border-top-colors": ["color", "systemColor"],
- "-moz-border-right-colors": ["color", "systemColor"],
- "-moz-border-bottom-colors": ["color", "systemColor"],
- "-moz-border-left-colors": ["color", "systemColor"],
- "-moz-box-align": ["mozBoxAlign"],
- "-moz-box-direction": ["mozBoxDirection"],
- "-moz-box-flex": [],
- "-moz-box-ordinal-group": [],
- "-moz-box-orient": ["mozBoxOrient"],
- "-moz-box-pack": ["mozBoxPack"],
- "-moz-box-sizing": ["mozBoxSizing"],
- "-moz-opacity": [],
- "-moz-user-focus": ["userFocus", "none"],
- "-moz-user-input": ["userInput"],
- "-moz-user-modify": [],
- "-moz-user-select": ["userSelect", "none"],
- "-moz-background-clip": [],
- "-moz-background-inline-policy": [],
- "-moz-background-origin": [],
- "-moz-binding": [],
- "-moz-column-count": [],
- "-moz-column-gap": [],
- "-moz-column-width": [],
- "-moz-image-region": []
-};
-
-this.inheritedStyleNames =
-{
- "border-collapse": 1,
- "border-spacing": 1,
- "border-style": 1,
- "caption-side": 1,
- "color": 1,
- "cursor": 1,
- "direction": 1,
- "empty-cells": 1,
- "font": 1,
- "font-family": 1,
- "font-size-adjust": 1,
- "font-size": 1,
- "font-style": 1,
- "font-variant": 1,
- "font-weight": 1,
- "letter-spacing": 1,
- "line-height": 1,
- "list-style": 1,
- "list-style-image": 1,
- "list-style-position": 1,
- "list-style-type": 1,
- "quotes": 1,
- "text-align": 1,
- "text-decoration": 1,
- "text-indent": 1,
- "text-shadow": 1,
- "text-transform": 1,
- "white-space": 1,
- "word-spacing": 1
-};
-
-this.cssKeywords =
-{
- "appearance":
- [
- "button",
- "button-small",
- "checkbox",
- "checkbox-container",
- "checkbox-small",
- "dialog",
- "listbox",
- "menuitem",
- "menulist",
- "menulist-button",
- "menulist-textfield",
- "menupopup",
- "progressbar",
- "radio",
- "radio-container",
- "radio-small",
- "resizer",
- "scrollbar",
- "scrollbarbutton-down",
- "scrollbarbutton-left",
- "scrollbarbutton-right",
- "scrollbarbutton-up",
- "scrollbartrack-horizontal",
- "scrollbartrack-vertical",
- "separator",
- "statusbar",
- "tab",
- "tab-left-edge",
- "tabpanels",
- "textfield",
- "toolbar",
- "toolbarbutton",
- "toolbox",
- "tooltip",
- "treeheadercell",
- "treeheadersortarrow",
- "treeitem",
- "treetwisty",
- "treetwistyopen",
- "treeview",
- "window"
- ],
-
- "systemColor":
- [
- "ActiveBorder",
- "ActiveCaption",
- "AppWorkspace",
- "Background",
- "ButtonFace",
- "ButtonHighlight",
- "ButtonShadow",
- "ButtonText",
- "CaptionText",
- "GrayText",
- "Highlight",
- "HighlightText",
- "InactiveBorder",
- "InactiveCaption",
- "InactiveCaptionText",
- "InfoBackground",
- "InfoText",
- "Menu",
- "MenuText",
- "Scrollbar",
- "ThreeDDarkShadow",
- "ThreeDFace",
- "ThreeDHighlight",
- "ThreeDLightShadow",
- "ThreeDShadow",
- "Window",
- "WindowFrame",
- "WindowText",
- "-moz-field",
- "-moz-fieldtext",
- "-moz-workspace",
- "-moz-visitedhyperlinktext",
- "-moz-use-text-color"
- ],
-
- "color":
- [
- "AliceBlue",
- "AntiqueWhite",
- "Aqua",
- "Aquamarine",
- "Azure",
- "Beige",
- "Bisque",
- "Black",
- "BlanchedAlmond",
- "Blue",
- "BlueViolet",
- "Brown",
- "BurlyWood",
- "CadetBlue",
- "Chartreuse",
- "Chocolate",
- "Coral",
- "CornflowerBlue",
- "Cornsilk",
- "Crimson",
- "Cyan",
- "DarkBlue",
- "DarkCyan",
- "DarkGoldenRod",
- "DarkGray",
- "DarkGreen",
- "DarkKhaki",
- "DarkMagenta",
- "DarkOliveGreen",
- "DarkOrange",
- "DarkOrchid",
- "DarkRed",
- "DarkSalmon",
- "DarkSeaGreen",
- "DarkSlateBlue",
- "DarkSlateGray",
- "DarkTurquoise",
- "DarkViolet",
- "DeepPink",
- "DarkSkyBlue",
- "DimGray",
- "DodgerBlue",
- "Feldspar",
- "FireBrick",
- "FloralWhite",
- "ForestGreen",
- "Fuchsia",
- "Gainsboro",
- "GhostWhite",
- "Gold",
- "GoldenRod",
- "Gray",
- "Green",
- "GreenYellow",
- "HoneyDew",
- "HotPink",
- "IndianRed",
- "Indigo",
- "Ivory",
- "Khaki",
- "Lavender",
- "LavenderBlush",
- "LawnGreen",
- "LemonChiffon",
- "LightBlue",
- "LightCoral",
- "LightCyan",
- "LightGoldenRodYellow",
- "LightGrey",
- "LightGreen",
- "LightPink",
- "LightSalmon",
- "LightSeaGreen",
- "LightSkyBlue",
- "LightSlateBlue",
- "LightSlateGray",
- "LightSteelBlue",
- "LightYellow",
- "Lime",
- "LimeGreen",
- "Linen",
- "Magenta",
- "Maroon",
- "MediumAquaMarine",
- "MediumBlue",
- "MediumOrchid",
- "MediumPurple",
- "MediumSeaGreen",
- "MediumSlateBlue",
- "MediumSpringGreen",
- "MediumTurquoise",
- "MediumVioletRed",
- "MidnightBlue",
- "MintCream",
- "MistyRose",
- "Moccasin",
- "NavajoWhite",
- "Navy",
- "OldLace",
- "Olive",
- "OliveDrab",
- "Orange",
- "OrangeRed",
- "Orchid",
- "PaleGoldenRod",
- "PaleGreen",
- "PaleTurquoise",
- "PaleVioletRed",
- "PapayaWhip",
- "PeachPuff",
- "Peru",
- "Pink",
- "Plum",
- "PowderBlue",
- "Purple",
- "Red",
- "RosyBrown",
- "RoyalBlue",
- "SaddleBrown",
- "Salmon",
- "SandyBrown",
- "SeaGreen",
- "SeaShell",
- "Sienna",
- "Silver",
- "SkyBlue",
- "SlateBlue",
- "SlateGray",
- "Snow",
- "SpringGreen",
- "SteelBlue",
- "Tan",
- "Teal",
- "Thistle",
- "Tomato",
- "Turquoise",
- "Violet",
- "VioletRed",
- "Wheat",
- "White",
- "WhiteSmoke",
- "Yellow",
- "YellowGreen",
- "transparent",
- "invert"
- ],
-
- "auto":
- [
- "auto"
- ],
-
- "none":
- [
- "none"
- ],
-
- "captionSide":
- [
- "top",
- "bottom",
- "left",
- "right"
- ],
-
- "clear":
- [
- "left",
- "right",
- "both"
- ],
-
- "cursor":
- [
- "auto",
- "cell",
- "context-menu",
- "crosshair",
- "default",
- "help",
- "pointer",
- "progress",
- "move",
- "e-resize",
- "all-scroll",
- "ne-resize",
- "nw-resize",
- "n-resize",
- "se-resize",
- "sw-resize",
- "s-resize",
- "w-resize",
- "ew-resize",
- "ns-resize",
- "nesw-resize",
- "nwse-resize",
- "col-resize",
- "row-resize",
- "text",
- "vertical-text",
- "wait",
- "alias",
- "copy",
- "move",
- "no-drop",
- "not-allowed",
- "-moz-alias",
- "-moz-cell",
- "-moz-copy",
- "-moz-grab",
- "-moz-grabbing",
- "-moz-contextmenu",
- "-moz-zoom-in",
- "-moz-zoom-out",
- "-moz-spinning"
- ],
-
- "direction":
- [
- "ltr",
- "rtl"
- ],
-
- "bgAttachment":
- [
- "scroll",
- "fixed"
- ],
-
- "bgPosition":
- [
- "top",
- "center",
- "bottom",
- "left",
- "right"
- ],
-
- "bgRepeat":
- [
- "repeat",
- "repeat-x",
- "repeat-y",
- "no-repeat"
- ],
-
- "borderStyle":
- [
- "hidden",
- "dotted",
- "dashed",
- "solid",
- "double",
- "groove",
- "ridge",
- "inset",
- "outset",
- "-moz-bg-inset",
- "-moz-bg-outset",
- "-moz-bg-solid"
- ],
-
- "borderCollapse":
- [
- "collapse",
- "separate"
- ],
-
- "overflow":
- [
- "visible",
- "hidden",
- "scroll",
- "-moz-scrollbars-horizontal",
- "-moz-scrollbars-none",
- "-moz-scrollbars-vertical"
- ],
-
- "listStyleType":
- [
- "disc",
- "circle",
- "square",
- "decimal",
- "decimal-leading-zero",
- "lower-roman",
- "upper-roman",
- "lower-greek",
- "lower-alpha",
- "lower-latin",
- "upper-alpha",
- "upper-latin",
- "hebrew",
- "armenian",
- "georgian",
- "cjk-ideographic",
- "hiragana",
- "katakana",
- "hiragana-iroha",
- "katakana-iroha",
- "inherit"
- ],
-
- "listStylePosition":
- [
- "inside",
- "outside"
- ],
-
- "content":
- [
- "open-quote",
- "close-quote",
- "no-open-quote",
- "no-close-quote",
- "inherit"
- ],
-
- "fontStyle":
- [
- "normal",
- "italic",
- "oblique",
- "inherit"
- ],
-
- "fontVariant":
- [
- "normal",
- "small-caps",
- "inherit"
- ],
-
- "fontWeight":
- [
- "normal",
- "bold",
- "bolder",
- "lighter",
- "inherit"
- ],
-
- "fontSize":
- [
- "xx-small",
- "x-small",
- "small",
- "medium",
- "large",
- "x-large",
- "xx-large",
- "smaller",
- "larger"
- ],
-
- "fontFamily":
- [
- "Arial",
- "Comic Sans MS",
- "Georgia",
- "Tahoma",
- "Verdana",
- "Times New Roman",
- "Trebuchet MS",
- "Lucida Grande",
- "Helvetica",
- "serif",
- "sans-serif",
- "cursive",
- "fantasy",
- "monospace",
- "caption",
- "icon",
- "menu",
- "message-box",
- "small-caption",
- "status-bar",
- "inherit"
- ],
-
- "display":
- [
- "block",
- "inline",
- "inline-block",
- "list-item",
- "marker",
- "run-in",
- "compact",
- "table",
- "inline-table",
- "table-row-group",
- "table-column",
- "table-column-group",
- "table-header-group",
- "table-footer-group",
- "table-row",
- "table-cell",
- "table-caption",
- "-moz-box",
- "-moz-compact",
- "-moz-deck",
- "-moz-grid",
- "-moz-grid-group",
- "-moz-grid-line",
- "-moz-groupbox",
- "-moz-inline-block",
- "-moz-inline-box",
- "-moz-inline-grid",
- "-moz-inline-stack",
- "-moz-inline-table",
- "-moz-marker",
- "-moz-popup",
- "-moz-runin",
- "-moz-stack"
- ],
-
- "position":
- [
- "static",
- "relative",
- "absolute",
- "fixed",
- "inherit"
- ],
-
- "float":
- [
- "left",
- "right"
- ],
-
- "textAlign":
- [
- "left",
- "right",
- "center",
- "justify"
- ],
-
- "tableLayout":
- [
- "fixed"
- ],
-
- "textDecoration":
- [
- "underline",
- "overline",
- "line-through",
- "blink"
- ],
-
- "textTransform":
- [
- "capitalize",
- "lowercase",
- "uppercase",
- "inherit"
- ],
-
- "unicodeBidi":
- [
- "normal",
- "embed",
- "bidi-override"
- ],
-
- "whiteSpace":
- [
- "normal",
- "pre",
- "nowrap"
- ],
-
- "verticalAlign":
- [
- "baseline",
- "sub",
- "super",
- "top",
- "text-top",
- "middle",
- "bottom",
- "text-bottom",
- "inherit"
- ],
-
- "thickness":
- [
- "thin",
- "medium",
- "thick"
- ],
-
- "userFocus":
- [
- "ignore",
- "normal"
- ],
-
- "userInput":
- [
- "disabled",
- "enabled"
- ],
-
- "userSelect":
- [
- "normal"
- ],
-
- "mozBoxSizing":
- [
- "content-box",
- "padding-box",
- "border-box"
- ],
-
- "mozBoxAlign":
- [
- "start",
- "center",
- "end",
- "baseline",
- "stretch"
- ],
-
- "mozBoxDirection":
- [
- "normal",
- "reverse"
- ],
-
- "mozBoxOrient":
- [
- "horizontal",
- "vertical"
- ],
-
- "mozBoxPack":
- [
- "start",
- "center",
- "end"
- ]
-};
-
-this.nonEditableTags =
-{
- "HTML": 1,
- "HEAD": 1,
- "html": 1,
- "head": 1
-};
-
-this.innerEditableTags =
-{
- "BODY": 1,
- "body": 1
-};
-
-this.selfClosingTags =
-{ // End tags for void elements are forbidden http://wiki.whatwg.org/wiki/HTML_vs._XHTML
- "meta": 1,
- "link": 1,
- "area": 1,
- "base": 1,
- "col": 1,
- "input": 1,
- "img": 1,
- "br": 1,
- "hr": 1,
- "param":1,
- "embed":1
-};
-
-var invisibleTags = this.invisibleTags =
-{
- "HTML": 1,
- "HEAD": 1,
- "TITLE": 1,
- "META": 1,
- "LINK": 1,
- "STYLE": 1,
- "SCRIPT": 1,
- "NOSCRIPT": 1,
- "BR": 1,
- "PARAM": 1,
- "COL": 1,
-
- "html": 1,
- "head": 1,
- "title": 1,
- "meta": 1,
- "link": 1,
- "style": 1,
- "script": 1,
- "noscript": 1,
- "br": 1,
- "param": 1,
- "col": 1
- /*
- "window": 1,
- "browser": 1,
- "frame": 1,
- "tabbrowser": 1,
- "WINDOW": 1,
- "BROWSER": 1,
- "FRAME": 1,
- "TABBROWSER": 1,
- */
-};
-
-
-if (typeof KeyEvent == "undefined") {
- this.KeyEvent = {
- DOM_VK_CANCEL: 3,
- DOM_VK_HELP: 6,
- DOM_VK_BACK_SPACE: 8,
- DOM_VK_TAB: 9,
- DOM_VK_CLEAR: 12,
- DOM_VK_RETURN: 13,
- DOM_VK_ENTER: 14,
- DOM_VK_SHIFT: 16,
- DOM_VK_CONTROL: 17,
- DOM_VK_ALT: 18,
- DOM_VK_PAUSE: 19,
- DOM_VK_CAPS_LOCK: 20,
- DOM_VK_ESCAPE: 27,
- DOM_VK_SPACE: 32,
- DOM_VK_PAGE_UP: 33,
- DOM_VK_PAGE_DOWN: 34,
- DOM_VK_END: 35,
- DOM_VK_HOME: 36,
- DOM_VK_LEFT: 37,
- DOM_VK_UP: 38,
- DOM_VK_RIGHT: 39,
- DOM_VK_DOWN: 40,
- DOM_VK_PRINTSCREEN: 44,
- DOM_VK_INSERT: 45,
- DOM_VK_DELETE: 46,
- DOM_VK_0: 48,
- DOM_VK_1: 49,
- DOM_VK_2: 50,
- DOM_VK_3: 51,
- DOM_VK_4: 52,
- DOM_VK_5: 53,
- DOM_VK_6: 54,
- DOM_VK_7: 55,
- DOM_VK_8: 56,
- DOM_VK_9: 57,
- DOM_VK_SEMICOLON: 59,
- DOM_VK_EQUALS: 61,
- DOM_VK_A: 65,
- DOM_VK_B: 66,
- DOM_VK_C: 67,
- DOM_VK_D: 68,
- DOM_VK_E: 69,
- DOM_VK_F: 70,
- DOM_VK_G: 71,
- DOM_VK_H: 72,
- DOM_VK_I: 73,
- DOM_VK_J: 74,
- DOM_VK_K: 75,
- DOM_VK_L: 76,
- DOM_VK_M: 77,
- DOM_VK_N: 78,
- DOM_VK_O: 79,
- DOM_VK_P: 80,
- DOM_VK_Q: 81,
- DOM_VK_R: 82,
- DOM_VK_S: 83,
- DOM_VK_T: 84,
- DOM_VK_U: 85,
- DOM_VK_V: 86,
- DOM_VK_W: 87,
- DOM_VK_X: 88,
- DOM_VK_Y: 89,
- DOM_VK_Z: 90,
- DOM_VK_CONTEXT_MENU: 93,
- DOM_VK_NUMPAD0: 96,
- DOM_VK_NUMPAD1: 97,
- DOM_VK_NUMPAD2: 98,
- DOM_VK_NUMPAD3: 99,
- DOM_VK_NUMPAD4: 100,
- DOM_VK_NUMPAD5: 101,
- DOM_VK_NUMPAD6: 102,
- DOM_VK_NUMPAD7: 103,
- DOM_VK_NUMPAD8: 104,
- DOM_VK_NUMPAD9: 105,
- DOM_VK_MULTIPLY: 106,
- DOM_VK_ADD: 107,
- DOM_VK_SEPARATOR: 108,
- DOM_VK_SUBTRACT: 109,
- DOM_VK_DECIMAL: 110,
- DOM_VK_DIVIDE: 111,
- DOM_VK_F1: 112,
- DOM_VK_F2: 113,
- DOM_VK_F3: 114,
- DOM_VK_F4: 115,
- DOM_VK_F5: 116,
- DOM_VK_F6: 117,
- DOM_VK_F7: 118,
- DOM_VK_F8: 119,
- DOM_VK_F9: 120,
- DOM_VK_F10: 121,
- DOM_VK_F11: 122,
- DOM_VK_F12: 123,
- DOM_VK_F13: 124,
- DOM_VK_F14: 125,
- DOM_VK_F15: 126,
- DOM_VK_F16: 127,
- DOM_VK_F17: 128,
- DOM_VK_F18: 129,
- DOM_VK_F19: 130,
- DOM_VK_F20: 131,
- DOM_VK_F21: 132,
- DOM_VK_F22: 133,
- DOM_VK_F23: 134,
- DOM_VK_F24: 135,
- DOM_VK_NUM_LOCK: 144,
- DOM_VK_SCROLL_LOCK: 145,
- DOM_VK_COMMA: 188,
- DOM_VK_PERIOD: 190,
- DOM_VK_SLASH: 191,
- DOM_VK_BACK_QUOTE: 192,
- DOM_VK_OPEN_BRACKET: 219,
- DOM_VK_BACK_SLASH: 220,
- DOM_VK_CLOSE_BRACKET: 221,
- DOM_VK_QUOTE: 222,
- DOM_VK_META: 224
- };
-}
-
-
-// ************************************************************************************************
-// Ajax
-
-/**
- * @namespace
- */
-this.Ajax =
-{
-
- requests: [],
- transport: null,
- states: ["Uninitialized","Loading","Loaded","Interactive","Complete"],
-
- initialize: function()
- {
- this.transport = FBL.getNativeXHRObject();
- },
-
- getXHRObject: function()
- {
- var xhrObj = false;
- try
- {
- xhrObj = new XMLHttpRequest();
- }
- catch(e)
- {
- var progid = [
- "MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0",
- "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"
- ];
-
- for ( var i=0; i < progid.length; ++i ) {
- try
- {
- xhrObj = new ActiveXObject(progid[i]);
- }
- catch(e)
- {
- continue;
- }
- break;
- }
- }
- finally
- {
- return xhrObj;
- }
- },
-
-
- /**
- * Create a AJAX request.
- *
- * @name request
- * @param {Object} options request options
- * @param {String} options.url URL to be requested
- * @param {String} options.type Request type ("get" ou "post"). Default is "get".
- * @param {Boolean} options.async Asynchronous flag. Default is "true".
- * @param {String} options.dataType Data type ("text", "html", "xml" or "json"). Default is "text".
- * @param {String} options.contentType Content-type of the data being sent. Default is "application/x-www-form-urlencoded".
- * @param {Function} options.onLoading onLoading callback
- * @param {Function} options.onLoaded onLoaded callback
- * @param {Function} options.onInteractive onInteractive callback
- * @param {Function} options.onComplete onComplete callback
- * @param {Function} options.onUpdate onUpdate callback
- * @param {Function} options.onSuccess onSuccess callback
- * @param {Function} options.onFailure onFailure callback
- */
- request: function(options)
- {
- // process options
- var o = FBL.extend(
- {
- // default values
- type: "get",
- async: true,
- dataType: "text",
- contentType: "application/x-www-form-urlencoded"
- },
- options || {}
- );
-
- this.requests.push(o);
-
- var s = this.getState();
- if (s == "Uninitialized" || s == "Complete" || s == "Loaded")
- this.sendRequest();
- },
-
- serialize: function(data)
- {
- var r = [""], rl = 0;
- if (data) {
- if (typeof data == "string") r[rl++] = data;
-
- else if (data.innerHTML && data.elements) {
- for (var i=0,el,l=(el=data.elements).length; i < l; i++)
- if (el[i].name) {
- r[rl++] = encodeURIComponent(el[i].name);
- r[rl++] = "=";
- r[rl++] = encodeURIComponent(el[i].value);
- r[rl++] = "&";
- }
-
- } else
- for(var param in data) {
- r[rl++] = encodeURIComponent(param);
- r[rl++] = "=";
- r[rl++] = encodeURIComponent(data[param]);
- r[rl++] = "&";
- }
- }
- return r.join("").replace(/&$/, "");
- },
-
- sendRequest: function()
- {
- var t = FBL.Ajax.transport, r = FBL.Ajax.requests.shift(), data;
-
- // open XHR object
- t.open(r.type, r.url, r.async);
-
- //setRequestHeaders();
-
- // indicates that it is a XHR request to the server
- t.setRequestHeader("X-Requested-With", "XMLHttpRequest");
-
- // if data is being sent, sets the appropriate content-type
- if (data = FBL.Ajax.serialize(r.data))
- t.setRequestHeader("Content-Type", r.contentType);
-
- /** @ignore */
- // onreadystatechange handler
- t.onreadystatechange = function()
- {
- FBL.Ajax.onStateChange(r);
- };
-
- // send the request
- t.send(data);
- },
-
- /**
- * Handles the state change
- */
- onStateChange: function(options)
- {
- var fn, o = options, t = this.transport;
- var state = this.getState(t);
-
- if (fn = o["on" + state]) fn(this.getResponse(o), o);
-
- if (state == "Complete")
- {
- var success = t.status == 200, response = this.getResponse(o);
-
- if (fn = o["onUpdate"])
- fn(response, o);
-
- if (fn = o["on" + (success ? "Success" : "Failure")])
- fn(response, o);
-
- t.onreadystatechange = FBL.emptyFn;
-
- if (this.requests.length > 0)
- setTimeout(this.sendRequest, 10);
- }
- },
-
- /**
- * gets the appropriate response value according the type
- */
- getResponse: function(options)
- {
- var t = this.transport, type = options.dataType;
-
- if (t.status != 200) return t.statusText;
- else if (type == "text") return t.responseText;
- else if (type == "html") return t.responseText;
- else if (type == "xml") return t.responseXML;
- else if (type == "json") return eval("(" + t.responseText + ")");
- },
-
- /**
- * returns the current state of the XHR object
- */
- getState: function()
- {
- return this.states[this.transport.readyState];
- }
-
-};
-
-
-// ************************************************************************************************
-// Cookie, from http://www.quirksmode.org/js/cookies.html
-
-this.createCookie = function(name,value,days)
-{
- if ('cookie' in document)
- {
- if (days)
- {
- var date = new Date();
- date.setTime(date.getTime()+(days*24*60*60*1000));
- var expires = "; expires="+date.toGMTString();
- }
- else
- var expires = "";
-
- document.cookie = name+"="+value+expires+"; path=/";
- }
-};
-
-this.readCookie = function (name)
-{
- if ('cookie' in document)
- {
- var nameEQ = name + "=";
- var ca = document.cookie.split(';');
-
- for(var i=0; i < ca.length; i++)
- {
- var c = ca[i];
- while (c.charAt(0)==' ') c = c.substring(1,c.length);
- if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
- }
- }
-
- return null;
-};
-
-this.removeCookie = function(name)
-{
- this.createCookie(name, "", -1);
-};
-
-
-// ************************************************************************************************
-// http://www.mister-pixel.com/#Content__state=is_that_simple
-var fixIE6BackgroundImageCache = function(doc)
-{
- doc = doc || document;
- try
- {
- doc.execCommand("BackgroundImageCache", false, true);
- }
- catch(E)
- {
-
- }
-};
-
-// ************************************************************************************************
-// calculatePixelsPerInch
-
-var resetStyle = "margin:0; padding:0; border:0; position:absolute; overflow:hidden; display:block;";
-
-var calculatePixelsPerInch = function calculatePixelsPerInch(doc, body)
-{
- var inch = FBL.createGlobalElement("div");
- inch.style.cssText = resetStyle + "width:1in; height:1in; position:absolute; top:-1234px; left:-1234px;";
- body.appendChild(inch);
-
- FBL.pixelsPerInch = {
- x: inch.offsetWidth,
- y: inch.offsetHeight
- };
-
- body.removeChild(inch);
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-this.SourceLink = function(url, line, type, object, instance)
-{
- this.href = url;
- this.instance = instance;
- this.line = line;
- this.type = type;
- this.object = object;
-};
-
-this.SourceLink.prototype =
-{
- toString: function()
- {
- return this.href;
- },
- toJSON: function() // until 3.1...
- {
- return "{\"href\":\""+this.href+"\", "+
- (this.line?("\"line\":"+this.line+","):"")+
- (this.type?(" \"type\":\""+this.type+"\","):"")+
- "}";
- }
-
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-this.SourceText = function(lines, owner)
-{
- this.lines = lines;
- this.owner = owner;
-};
-
-this.SourceText.getLineAsHTML = function(lineNo)
-{
- return escapeForSourceLine(this.lines[lineNo-1]);
-};
-
-
-// ************************************************************************************************
-}).apply(FBL);
-
-/* See license.txt for terms of usage */
-
-FBL.ns( /** @scope s_i18n */ function() { with (FBL) {
-// ************************************************************************************************
-
-// TODO: xxxpedro localization
-var oSTR =
-{
- "NoMembersWarning": "There are no properties to show for this object.",
-
- "EmptyStyleSheet": "There are no rules in this stylesheet.",
- "EmptyElementCSS": "This element has no style rules.",
- "AccessRestricted": "Access to restricted URI denied.",
-
- "net.label.Parameters": "Parameters",
- "net.label.Source": "Source",
- "URLParameters": "Params",
-
- "EditStyle": "Edit Element Style...",
- "NewRule": "New Rule...",
-
- "NewProp": "New Property...",
- "EditProp": 'Edit "%s"',
- "DeleteProp": 'Delete "%s"',
- "DisableProp": 'Disable "%s"'
-};
-
-// ************************************************************************************************
-
-FBL.$STR = function(name)
-{
- return oSTR.hasOwnProperty(name) ? oSTR[name] : name;
-};
-
-FBL.$STRF = function(name, args)
-{
- if (!oSTR.hasOwnProperty(name)) return name;
-
- var format = oSTR[name];
- var objIndex = 0;
-
- var parts = parseFormat(format);
- var trialIndex = objIndex;
- var objects = args;
-
- for (var i= 0; i < parts.length; i++)
- {
- var part = parts[i];
- if (part && typeof(part) == "object")
- {
- if (++trialIndex > objects.length) // then too few parameters for format, assume unformatted.
- {
- format = "";
- objIndex = -1;
- parts.length = 0;
- break;
- }
- }
-
- }
-
- var result = [];
- for (var i = 0; i < parts.length; ++i)
- {
- var part = parts[i];
- if (part && typeof(part) == "object")
- {
- result.push(""+args.shift());
- }
- else
- result.push(part);
- }
-
- return result.join("");
-};
-
-// ************************************************************************************************
-
-var parseFormat = function parseFormat(format)
-{
- var parts = [];
- if (format.length <= 0)
- return parts;
-
- var reg = /((^%|.%)(\d+)?(\.)([a-zA-Z]))|((^%|.%)([a-zA-Z]))/;
- for (var m = reg.exec(format); m; m = reg.exec(format))
- {
- if (m[0].substr(0, 2) == "%%")
- {
- parts.push(format.substr(0, m.index));
- parts.push(m[0].substr(1));
- }
- else
- {
- var type = m[8] ? m[8] : m[5];
- var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
-
- var rep = null;
- switch (type)
- {
- case "s":
- rep = FirebugReps.Text;
- break;
- case "f":
- case "i":
- case "d":
- rep = FirebugReps.Number;
- break;
- case "o":
- rep = null;
- break;
- }
-
- parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
- parts.push({rep: rep, precision: precision, type: ("%" + type)});
- }
-
- format = format.substr(m.index+m[0].length);
- }
-
- parts.push(format);
- return parts;
-};
-
-// ************************************************************************************************
-}});
-
-/* See license.txt for terms of usage */
-
-FBL.ns( /** @scope s_firebug */ function() { with (FBL) {
-// ************************************************************************************************
-
-// ************************************************************************************************
-// Globals
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// Internals
-
-var modules = [];
-var panelTypes = [];
-var panelTypeMap = {};
-var reps = [];
-
-var parentPanelMap = {};
-
-
-// ************************************************************************************************
-// Firebug
-
-/**
- * @namespace describe Firebug
- * @exports FBL.Firebug as Firebug
- */
-FBL.Firebug =
-{
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- version: "Firebug Lite 1.4.0",
- revision: "$Revision$",
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- modules: modules,
- panelTypes: panelTypes,
- panelTypeMap: panelTypeMap,
- reps: reps,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Initialization
-
- initialize: function()
- {
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.initialize", "initializing application");
-
- Firebug.browser = new Context(Env.browser);
- Firebug.context = Firebug.browser;
-
- Firebug.loadPrefs();
- Firebug.context.persistedState.isOpen = false;
-
- // Document must be cached before chrome initialization
- cacheDocument();
-
- if (Firebug.Inspector && Firebug.Inspector.create)
- Firebug.Inspector.create();
-
- if (FBL.CssAnalyzer && FBL.CssAnalyzer.processAllStyleSheets)
- FBL.CssAnalyzer.processAllStyleSheets(Firebug.browser.document);
-
- FirebugChrome.initialize();
-
- dispatch(modules, "initialize", []);
-
- if (Firebug.disableResourceFetching)
- Firebug.Console.logFormatted(["Some Firebug Lite features are not working because " +
- "resource fetching is disabled. To enabled it set the Firebug Lite option " +
- "\"disableResourceFetching\" to \"false\". More info at " +
- "http://getfirebug.com/firebuglite#Options"],
- Firebug.context, "warn");
-
- if (Env.onLoad)
- {
- var onLoad = Env.onLoad;
- delete Env.onLoad;
-
- setTimeout(onLoad, 200);
- }
- },
-
- shutdown: function()
- {
- if (Firebug.saveCookies)
- Firebug.savePrefs();
-
- if (Firebug.Inspector)
- Firebug.Inspector.destroy();
-
- dispatch(modules, "shutdown", []);
-
- var chromeMap = FirebugChrome.chromeMap;
-
- for (var name in chromeMap)
- {
- if (chromeMap.hasOwnProperty(name))
- {
- try
- {
- chromeMap[name].destroy();
- }
- catch(E)
- {
- if (FBTrace.DBG_ERRORS) FBTrace.sysout("chrome.destroy() failed to: " + name);
- }
- }
- }
-
- Firebug.Lite.Cache.Element.clear();
- Firebug.Lite.Cache.StyleSheet.clear();
-
- Firebug.browser = null;
- Firebug.context = null;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Registration
-
- registerModule: function()
- {
- modules.push.apply(modules, arguments);
-
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.registerModule");
- },
-
- registerPanel: function()
- {
- panelTypes.push.apply(panelTypes, arguments);
-
- for (var i = 0, panelType; panelType = arguments[i]; ++i)
- {
- panelTypeMap[panelType.prototype.name] = arguments[i];
-
- if (panelType.prototype.parentPanel)
- parentPanelMap[panelType.prototype.parentPanel] = 1;
- }
-
- if (FBTrace.DBG_INITIALIZE)
- for (var i = 0; i < arguments.length; ++i)
- FBTrace.sysout("Firebug.registerPanel", arguments[i].prototype.name);
- },
-
- registerRep: function()
- {
- reps.push.apply(reps, arguments);
- },
-
- unregisterRep: function()
- {
- for (var i = 0; i < arguments.length; ++i)
- remove(reps, arguments[i]);
- },
-
- setDefaultReps: function(funcRep, rep)
- {
- FBL.defaultRep = rep;
- FBL.defaultFuncRep = funcRep;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Reps
-
- getRep: function(object)
- {
- var type = typeof object;
- if (isIE && isFunction(object))
- type = "function";
-
- for (var i = 0; i < reps.length; ++i)
- {
- var rep = reps[i];
- try
- {
- if (rep.supportsObject(object, type))
- {
- if (FBTrace.DBG_DOM)
- FBTrace.sysout("getRep type: "+type+" object: "+object, rep);
- return rep;
- }
- }
- catch (exc)
- {
- if (FBTrace.DBG_ERRORS)
- {
- FBTrace.sysout("firebug.getRep FAILS: ", exc.message || exc);
- FBTrace.sysout("firebug.getRep reps["+i+"/"+reps.length+"]: Rep="+reps[i].className);
- // TODO: xxxpedro add trace to FBTrace logs like in Firebug
- //firebug.trace();
- }
- }
- }
-
- return (type == 'function') ? defaultFuncRep : defaultRep;
- },
-
- getRepObject: function(node)
- {
- var target = null;
- for (var child = node; child; child = child.parentNode)
- {
- if (hasClass(child, "repTarget"))
- target = child;
-
- if (child.repObject)
- {
- if (!target && hasClass(child, "repIgnore"))
- break;
- else
- return child.repObject;
- }
- }
- },
-
- getRepNode: function(node)
- {
- for (var child = node; child; child = child.parentNode)
- {
- if (child.repObject)
- return child;
- }
- },
-
- getElementByRepObject: function(element, object)
- {
- for (var child = element.firstChild; child; child = child.nextSibling)
- {
- if (child.repObject == object)
- return child;
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Preferences
-
- getPref: function(name)
- {
- return Firebug[name];
- },
-
- setPref: function(name, value)
- {
- Firebug[name] = value;
-
- Firebug.savePrefs();
- },
-
- setPrefs: function(prefs)
- {
- for (var name in prefs)
- {
- if (prefs.hasOwnProperty(name))
- Firebug[name] = prefs[name];
- }
-
- Firebug.savePrefs();
- },
-
- restorePrefs: function()
- {
- var Options = Env.DefaultOptions;
-
- for (var name in Options)
- {
- Firebug[name] = Options[name];
- }
- },
-
- loadPrefs: function()
- {
- this.restorePrefs();
-
- var prefs = Store.get("FirebugLite") || {};
- var options = prefs.options;
- var persistedState = prefs.persistedState || FBL.defaultPersistedState;
-
- for (var name in options)
- {
- if (options.hasOwnProperty(name))
- Firebug[name] = options[name];
- }
-
- if (Firebug.context && persistedState)
- Firebug.context.persistedState = persistedState;
- },
-
- savePrefs: function()
- {
- var prefs = {
- options: {}
- };
-
- var EnvOptions = Env.Options;
- var options = prefs.options;
- for (var name in EnvOptions)
- {
- if (EnvOptions.hasOwnProperty(name))
- {
- options[name] = Firebug[name];
- }
- }
-
- var persistedState = Firebug.context.persistedState;
- if (!persistedState)
- {
- persistedState = Firebug.context.persistedState = FBL.defaultPersistedState;
- }
-
- prefs.persistedState = persistedState;
-
- Store.set("FirebugLite", prefs);
- },
-
- erasePrefs: function()
- {
- Store.remove("FirebugLite");
- this.restorePrefs();
- }
-};
-
-Firebug.restorePrefs();
-
-// xxxpedro should we remove this?
-window.Firebug = FBL.Firebug;
-
-if (!Env.Options.enablePersistent ||
- Env.Options.enablePersistent && Env.isChromeContext ||
- Env.isDebugMode)
- Env.browser.window.Firebug = FBL.Firebug;
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// Other methods
-
-FBL.cacheDocument = function cacheDocument()
-{
- var ElementCache = Firebug.Lite.Cache.Element;
- var els = Firebug.browser.document.getElementsByTagName("*");
- for (var i=0, l=els.length, el; i<l; i++)
- {
- el = els[i];
- ElementCache(el);
- }
-};
-
-// ************************************************************************************************
-
-/**
- * @class
- *
- * Support for listeners registration. This object also extended by Firebug.Module so,
- * all modules supports listening automatically. Notice that array of listeners
- * is created for each intance of a module within initialize method. Thus all derived
- * module classes must ensure that Firebug.Module.initialize method is called for the
- * super class.
- */
-Firebug.Listener = function()
-{
- // The array is created when the first listeners is added.
- // It can't be created here since derived objects would share
- // the same array.
- this.fbListeners = null;
-};
-
-Firebug.Listener.prototype =
-{
- addListener: function(listener)
- {
- if (!this.fbListeners)
- this.fbListeners = []; // delay the creation until the objects are created so 'this' causes new array for each module
-
- this.fbListeners.push(listener);
- },
-
- removeListener: function(listener)
- {
- remove(this.fbListeners, listener); // if this.fbListeners is null, remove is being called with no add
- }
-};
-
-// ************************************************************************************************
-
-
-// ************************************************************************************************
-// Module
-
-/**
- * @module Base class for all modules. Every derived module object must be registered using
- * <code>Firebug.registerModule</code> method. There is always one instance of a module object
- * per browser window.
- * @extends Firebug.Listener
- */
-Firebug.Module = extend(new Firebug.Listener(),
-/** @extend Firebug.Module */
-{
- /**
- * Called when the window is opened.
- */
- initialize: function()
- {
- },
-
- /**
- * Called when the window is closed.
- */
- shutdown: function()
- {
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- /**
- * Called when a new context is created but before the page is loaded.
- */
- initContext: function(context)
- {
- },
-
- /**
- * Called after a context is detached to a separate window;
- */
- reattachContext: function(browser, context)
- {
- },
-
- /**
- * Called when a context is destroyed. Module may store info on persistedState for reloaded pages.
- */
- destroyContext: function(context, persistedState)
- {
- },
-
- // Called when a FF tab is create or activated (user changes FF tab)
- // Called after context is created or with context == null (to abort?)
- showContext: function(browser, context)
- {
- },
-
- /**
- * Called after a context's page gets DOMContentLoaded
- */
- loadedContext: function(context)
- {
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- showPanel: function(browser, panel)
- {
- },
-
- showSidePanel: function(browser, panel)
- {
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- updateOption: function(name, value)
- {
- },
-
- getObjectByURL: function(context, url)
- {
- }
-});
-
-// ************************************************************************************************
-// Panel
-
-/**
- * @panel Base class for all panels. Every derived panel must define a constructor and
- * register with "Firebug.registerPanel" method. An instance of the panel
- * object is created by the framework for each browser tab where Firebug is activated.
- */
-Firebug.Panel =
-{
- name: "HelloWorld",
- title: "Hello World!",
-
- parentPanel: null,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- options: {
- hasCommandLine: false,
- hasStatusBar: false,
- hasToolButtons: false,
-
- // Pre-rendered panels are those included in the skin file (firebug.html)
- isPreRendered: false,
- innerHTMLSync: false
-
- /*
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // To be used by external extensions
- panelHTML: "",
- panelCSS: "",
-
- toolButtonsHTML: ""
- /**/
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- tabNode: null,
- panelNode: null,
- sidePanelNode: null,
- statusBarNode: null,
- toolButtonsNode: null,
-
- panelBarNode: null,
-
- sidePanelBarBoxNode: null,
- sidePanelBarNode: null,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- sidePanelBar: null,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- searchable: false,
- editable: true,
- order: 2147483647,
- statusSeparator: "<",
-
- create: function(context, doc)
- {
- this.hasSidePanel = parentPanelMap.hasOwnProperty(this.name);
-
- this.panelBarNode = $("fbPanelBar1");
- this.sidePanelBarBoxNode = $("fbPanelBar2");
-
- if (this.hasSidePanel)
- {
- this.sidePanelBar = extend({}, PanelBar);
- this.sidePanelBar.create(this);
- }
-
- var options = this.options = extend(Firebug.Panel.options, this.options);
- var panelId = "fb" + this.name;
-
- if (options.isPreRendered)
- {
- this.panelNode = $(panelId);
-
- this.tabNode = $(panelId + "Tab");
- this.tabNode.style.display = "block";
-
- if (options.hasToolButtons)
- {
- this.toolButtonsNode = $(panelId + "Buttons");
- }
-
- if (options.hasStatusBar)
- {
- this.statusBarBox = $("fbStatusBarBox");
- this.statusBarNode = $(panelId + "StatusBar");
- }
- }
- else
- {
- var containerSufix = this.parentPanel ? "2" : "1";
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Create Panel
- var panelNode = this.panelNode = createElement("div", {
- id: panelId,
- className: "fbPanel"
- });
-
- $("fbPanel" + containerSufix).appendChild(panelNode);
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Create Panel Tab
- var tabHTML = '<span class="fbTabL"></span><span class="fbTabText">' +
- this.title + '</span><span class="fbTabR"></span>';
-
- var tabNode = this.tabNode = createElement("a", {
- id: panelId + "Tab",
- className: "fbTab fbHover",
- innerHTML: tabHTML
- });
-
- if (isIE6)
- {
- tabNode.href = "javascript:void(0)";
- }
-
- var panelBarNode = this.parentPanel ?
- Firebug.chrome.getPanel(this.parentPanel).sidePanelBarNode :
- this.panelBarNode;
-
- panelBarNode.appendChild(tabNode);
- tabNode.style.display = "block";
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // create ToolButtons
- if (options.hasToolButtons)
- {
- this.toolButtonsNode = createElement("span", {
- id: panelId + "Buttons",
- className: "fbToolbarButtons"
- });
-
- $("fbToolbarButtons").appendChild(this.toolButtonsNode);
- }
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // create StatusBar
- if (options.hasStatusBar)
- {
- this.statusBarBox = $("fbStatusBarBox");
-
- this.statusBarNode = createElement("span", {
- id: panelId + "StatusBar",
- className: "fbToolbarButtons fbStatusBar"
- });
-
- this.statusBarBox.appendChild(this.statusBarNode);
- }
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // create SidePanel
- }
-
- this.containerNode = this.panelNode.parentNode;
-
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.Panel.create", this.name);
-
- // xxxpedro contextMenu
- this.onContextMenu = bind(this.onContextMenu, this);
-
- /*
- this.context = context;
- this.document = doc;
-
- this.panelNode = doc.createElement("div");
- this.panelNode.ownerPanel = this;
-
- setClass(this.panelNode, "panelNode panelNode-"+this.name+" contextUID="+context.uid);
- doc.body.appendChild(this.panelNode);
-
- if (FBTrace.DBG_INITIALIZE)
- FBTrace.sysout("firebug.initialize panelNode for "+this.name+"\n");
-
- this.initializeNode(this.panelNode);
- /**/
- },
-
- destroy: function(state) // Panel may store info on state
- {
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.Panel.destroy", this.name);
-
- if (this.hasSidePanel)
- {
- this.sidePanelBar.destroy();
- this.sidePanelBar = null;
- }
-
- this.options = null;
- this.name = null;
- this.parentPanel = null;
-
- this.tabNode = null;
- this.panelNode = null;
- this.containerNode = null;
-
- this.toolButtonsNode = null;
- this.statusBarBox = null;
- this.statusBarNode = null;
-
- //if (this.panelNode)
- // delete this.panelNode.ownerPanel;
-
- //this.destroyNode();
- },
-
- initialize: function()
- {
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.Panel.initialize", this.name);
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- if (this.hasSidePanel)
- {
- this.sidePanelBar.initialize();
- }
-
- var options = this.options = extend(Firebug.Panel.options, this.options);
- var panelId = "fb" + this.name;
-
- this.panelNode = $(panelId);
-
- this.tabNode = $(panelId + "Tab");
- this.tabNode.style.display = "block";
-
- if (options.hasStatusBar)
- {
- this.statusBarBox = $("fbStatusBarBox");
- this.statusBarNode = $(panelId + "StatusBar");
- }
-
- if (options.hasToolButtons)
- {
- this.toolButtonsNode = $(panelId + "Buttons");
- }
-
- this.containerNode = this.panelNode.parentNode;
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // restore persistent state
- this.containerNode.scrollTop = this.lastScrollTop;
-
- // xxxpedro contextMenu
- addEvent(this.containerNode, "contextmenu", this.onContextMenu);
-
-
- /// TODO: xxxpedro infoTip Hack
- Firebug.chrome.currentPanel =
- Firebug.chrome.selectedPanel && Firebug.chrome.selectedPanel.sidePanelBar ?
- Firebug.chrome.selectedPanel.sidePanelBar.selectedPanel :
- Firebug.chrome.selectedPanel;
-
- Firebug.showInfoTips = true;
- if (Firebug.InfoTip)
- Firebug.InfoTip.initializeBrowser(Firebug.chrome);
- },
-
- shutdown: function()
- {
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.Panel.shutdown", this.name);
-
- /// TODO: xxxpedro infoTip Hack
- if (Firebug.InfoTip)
- Firebug.InfoTip.uninitializeBrowser(Firebug.chrome);
-
- if (Firebug.chrome.largeCommandLineVisible)
- Firebug.chrome.hideLargeCommandLine();
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- if (this.hasSidePanel)
- {
- // TODO: xxxpedro firebug1.3a6
- // new PanelBar mechanism will need to call shutdown to hide the panels (so it
- // doesn't appears in other panel's sidePanelBar. Therefore, we need to implement
- // a "remember selected panel" feature in the sidePanelBar
- //this.sidePanelBar.shutdown();
- }
-
- // store persistent state
- this.lastScrollTop = this.containerNode.scrollTop;
-
- // xxxpedro contextMenu
- removeEvent(this.containerNode, "contextmenu", this.onContextMenu);
- },
-
- detach: function(oldChrome, newChrome)
- {
- if (oldChrome && oldChrome.selectedPanel && oldChrome.selectedPanel.name == this.name)
- this.lastScrollTop = oldChrome.selectedPanel.containerNode.scrollTop;
- },
-
- reattach: function(doc)
- {
- if (this.options.innerHTMLSync)
- this.synchronizeUI();
- },
-
- synchronizeUI: function()
- {
- this.containerNode.scrollTop = this.lastScrollTop || 0;
- },
-
- show: function(state)
- {
- var options = this.options;
-
- if (options.hasStatusBar)
- {
- this.statusBarBox.style.display = "inline";
- this.statusBarNode.style.display = "inline";
- }
-
- if (options.hasToolButtons)
- {
- this.toolButtonsNode.style.display = "inline";
- }
-
- this.panelNode.style.display = "block";
-
- this.visible = true;
-
- if (!this.parentPanel)
- Firebug.chrome.layout(this);
- },
-
- hide: function(state)
- {
- var options = this.options;
-
- if (options.hasStatusBar)
- {
- this.statusBarBox.style.display = "none";
- this.statusBarNode.style.display = "none";
- }
-
- if (options.hasToolButtons)
- {
- this.toolButtonsNode.style.display = "none";
- }
-
- this.panelNode.style.display = "none";
-
- this.visible = false;
- },
-
- watchWindow: function(win)
- {
- },
-
- unwatchWindow: function(win)
- {
- },
-
- updateOption: function(name, value)
- {
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- /**
- * Toolbar helpers
- */
- showToolbarButtons: function(buttonsId, show)
- {
- try
- {
- if (!this.context.browser) // XXXjjb this is bug. Somehow the panel context is not FirebugContext.
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("firebug.Panel showToolbarButtons this.context has no browser, this:", this);
-
- return;
- }
- var buttons = this.context.browser.chrome.$(buttonsId);
- if (buttons)
- collapse(buttons, show ? "false" : "true");
- }
- catch (exc)
- {
- if (FBTrace.DBG_ERRORS)
- {
- FBTrace.dumpProperties("firebug.Panel showToolbarButtons FAILS", exc);
- if (!this.context.browser)FBTrace.dumpStack("firebug.Panel showToolbarButtons no browser");
- }
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- /**
- * Returns a number indicating the view's ability to inspect the object.
- *
- * Zero means not supported, and higher numbers indicate specificity.
- */
- supportsObject: function(object)
- {
- return 0;
- },
-
- hasObject: function(object) // beyond type testing, is this object selectable?
- {
- return false;
- },
-
- select: function(object, forceUpdate)
- {
- if (!object)
- object = this.getDefaultSelection(this.context);
-
- if(FBTrace.DBG_PANELS)
- FBTrace.sysout("firebug.select "+this.name+" forceUpdate: "+forceUpdate+" "+object+((object==this.selection)?"==":"!=")+this.selection);
-
- if (forceUpdate || object != this.selection)
- {
- this.selection = object;
- this.updateSelection(object);
-
- // TODO: xxxpedro
- // XXXjoe This is kind of cheating, but, feh.
- //Firebug.chrome.onPanelSelect(object, this);
- //if (uiListeners.length > 0)
- // dispatch(uiListeners, "onPanelSelect", [object, this]); // TODO: make Firebug.chrome a uiListener
- }
- },
-
- updateSelection: function(object)
- {
- },
-
- markChange: function(skipSelf)
- {
- if (this.dependents)
- {
- if (skipSelf)
- {
- for (var i = 0; i < this.dependents.length; ++i)
- {
- var panelName = this.dependents[i];
- if (panelName != this.name)
- this.context.invalidatePanels(panelName);
- }
- }
- else
- this.context.invalidatePanels.apply(this.context, this.dependents);
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- startInspecting: function()
- {
- },
-
- stopInspecting: function(object, cancelled)
- {
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- search: function(text, reverse)
- {
- },
-
- /**
- * Retrieves the search options that this modules supports.
- * This is used by the search UI to present the proper options.
- */
- getSearchOptionsMenuItems: function()
- {
- return [
- Firebug.Search.searchOptionMenu("search.Case Sensitive", "searchCaseSensitive")
- ];
- },
-
- /**
- * Navigates to the next document whose match parameter returns true.
- */
- navigateToNextDocument: function(match, reverse)
- {
- // This is an approximation of the UI that is displayed by the location
- // selector. This should be close enough, although it may be better
- // to simply generate the sorted list within the module, rather than
- // sorting within the UI.
- var self = this;
- function compare(a, b) {
- var locA = self.getObjectDescription(a);
- var locB = self.getObjectDescription(b);
- if(locA.path > locB.path)
- return 1;
- if(locA.path < locB.path)
- return -1;
- if(locA.name > locB.name)
- return 1;
- if(locA.name < locB.name)
- return -1;
- return 0;
- }
- var allLocs = this.getLocationList().sort(compare);
- for (var curPos = 0; curPos < allLocs.length && allLocs[curPos] != this.location; curPos++);
-
- function transformIndex(index) {
- if (reverse) {
- // For the reverse case we need to implement wrap around.
- var intermediate = curPos - index - 1;
- return (intermediate < 0 ? allLocs.length : 0) + intermediate;
- } else {
- return (curPos + index + 1) % allLocs.length;
- }
- };
-
- for (var next = 0; next < allLocs.length - 1; next++)
- {
- var object = allLocs[transformIndex(next)];
-
- if (match(object))
- {
- this.navigate(object);
- return object;
- }
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- // Called when "Options" clicked. Return array of
- // {label: 'name', nol10n: true, type: "checkbox", checked: <value>, command:function to set <value>}
- getOptionsMenuItems: function()
- {
- return null;
- },
-
- /*
- * Called by chrome.onContextMenu to build the context menu when this panel has focus.
- * See also FirebugRep for a similar function also called by onContextMenu
- * Extensions may monkey patch and chain off this call
- * @param object: the 'realObject', a model value, eg a DOM property
- * @param target: the HTML element clicked on.
- * @return an array of menu items.
- */
- getContextMenuItems: function(object, target)
- {
- return [];
- },
-
- getBreakOnMenuItems: function()
- {
- return [];
- },
-
- getEditor: function(target, value)
- {
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- getDefaultSelection: function()
- {
- return null;
- },
-
- browseObject: function(object)
- {
- },
-
- getPopupObject: function(target)
- {
- return Firebug.getRepObject(target);
- },
-
- getTooltipObject: function(target)
- {
- return Firebug.getRepObject(target);
- },
-
- showInfoTip: function(infoTip, x, y)
- {
-
- },
-
- getObjectPath: function(object)
- {
- return null;
- },
-
- // An array of objects that can be passed to getObjectLocation.
- // The list of things a panel can show, eg sourceFiles.
- // Only shown if panel.location defined and supportsObject true
- getLocationList: function()
- {
- return null;
- },
-
- getDefaultLocation: function()
- {
- return null;
- },
-
- getObjectLocation: function(object)
- {
- return "";
- },
-
- // Text for the location list menu eg script panel source file list
- // return.path: group/category label, return.name: item label
- getObjectDescription: function(object)
- {
- var url = this.getObjectLocation(object);
- return FBL.splitURLBase(url);
- },
-
- /*
- * UI signal that a tab needs attention, eg Script panel is currently stopped on a breakpoint
- * @param: show boolean, true turns on.
- */
- highlight: function(show)
- {
- var tab = this.getTab();
- if (!tab)
- return;
-
- if (show)
- tab.setAttribute("highlight", "true");
- else
- tab.removeAttribute("highlight");
- },
-
- getTab: function()
- {
- var chrome = Firebug.chrome;
-
- var tab = chrome.$("fbPanelBar2").getTab(this.name);
- if (!tab)
- tab = chrome.$("fbPanelBar1").getTab(this.name);
- return tab;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Support for Break On Next
-
- /**
- * Called by the framework when the user clicks on the Break On Next button.
- * @param {Boolean} armed Set to true if the Break On Next feature is
- * to be armed for action and set to false if the Break On Next should be disarmed.
- * If 'armed' is true, then the next call to shouldBreakOnNext should be |true|.
- */
- breakOnNext: function(armed)
- {
- },
-
- /**
- * Called when a panel is selected/displayed. The method should return true
- * if the Break On Next feature is currently armed for this panel.
- */
- shouldBreakOnNext: function()
- {
- return false;
- },
-
- /**
- * Returns labels for Break On Next tooltip (one for enabled and one for disabled state).
- * @param {Boolean} enabled Set to true if the Break On Next feature is
- * currently activated for this panel.
- */
- getBreakOnNextTooltip: function(enabled)
- {
- return null;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- // xxxpedro contextMenu
- onContextMenu: function(event)
- {
- if (!this.getContextMenuItems)
- return;
-
- cancelEvent(event, true);
-
- var target = event.target || event.srcElement;
-
- var menu = this.getContextMenuItems(this.selection, target);
- if (!menu)
- return;
-
- var contextMenu = new Menu(
- {
- id: "fbPanelContextMenu",
-
- items: menu
- });
-
- contextMenu.show(event.clientX, event.clientY);
-
- return true;
-
- /*
- // TODO: xxxpedro move code to somewhere. code to get cross-browser
- // window to screen coordinates
- var box = Firebug.browser.getElementPosition(Firebug.chrome.node);
-
- var screenY = 0;
-
- // Firefox
- if (typeof window.mozInnerScreenY != "undefined")
- {
- screenY = window.mozInnerScreenY;
- }
- // Chrome
- else if (typeof window.innerHeight != "undefined")
- {
- screenY = window.outerHeight - window.innerHeight;
- }
- // IE
- else if (typeof window.screenTop != "undefined")
- {
- screenY = window.screenTop;
- }
-
- contextMenu.show(event.screenX-box.left, event.screenY-screenY-box.top);
- /**/
- }
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-/**
- * MeasureBox
- * To get pixels size.width and size.height:
- * <ul><li> this.startMeasuring(view); </li>
- * <li> var size = this.measureText(lineNoCharsSpacer); </li>
- * <li> this.stopMeasuring(); </li>
- * </ul>
- *
- * @namespace
- */
-Firebug.MeasureBox =
-{
- startMeasuring: function(target)
- {
- if (!this.measureBox)
- {
- this.measureBox = target.ownerDocument.createElement("span");
- this.measureBox.className = "measureBox";
- }
-
- copyTextStyles(target, this.measureBox);
- target.ownerDocument.body.appendChild(this.measureBox);
- },
-
- getMeasuringElement: function()
- {
- return this.measureBox;
- },
-
- measureText: function(value)
- {
- this.measureBox.innerHTML = value ? escapeForSourceLine(value) : "m";
- return {width: this.measureBox.offsetWidth, height: this.measureBox.offsetHeight-1};
- },
-
- measureInputText: function(value)
- {
- value = value ? escapeForTextNode(value) : "m";
- if (!Firebug.showTextNodesWithWhitespace)
- value = value.replace(/\t/g,'mmmmmm').replace(/\ /g,'m');
- this.measureBox.innerHTML = value;
- return {width: this.measureBox.offsetWidth, height: this.measureBox.offsetHeight-1};
- },
-
- getBox: function(target)
- {
- var style = this.measureBox.ownerDocument.defaultView.getComputedStyle(this.measureBox, "");
- var box = getBoxFromStyles(style, this.measureBox);
- return box;
- },
-
- stopMeasuring: function()
- {
- this.measureBox.parentNode.removeChild(this.measureBox);
- }
-};
-
-
-// ************************************************************************************************
-if (FBL.domplate) Firebug.Rep = domplate(
-{
- className: "",
- inspectable: true,
-
- supportsObject: function(object, type)
- {
- return false;
- },
-
- inspectObject: function(object, context)
- {
- Firebug.chrome.select(object);
- },
-
- browseObject: function(object, context)
- {
- },
-
- persistObject: function(object, context)
- {
- },
-
- getRealObject: function(object, context)
- {
- return object;
- },
-
- getTitle: function(object)
- {
- var label = safeToString(object);
-
- var re = /\[object (.*?)\]/;
- var m = re.exec(label);
-
- ///return m ? m[1] : label;
-
- // if the label is in the "[object TYPE]" format return its type
- if (m)
- {
- return m[1];
- }
- // if it is IE we need to handle some special cases
- else if (
- // safeToString() fails to recognize some objects in IE
- isIE &&
- // safeToString() returns "[object]" for some objects like window.Image
- (label == "[object]" ||
- // safeToString() returns undefined for some objects like window.clientInformation
- typeof object == "object" && typeof label == "undefined")
- )
- {
- return "Object";
- }
- else
- {
- return label;
- }
- },
-
- getTooltip: function(object)
- {
- return null;
- },
-
- getContextMenuItems: function(object, target, context)
- {
- return [];
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Convenience for domplates
-
- STR: function(name)
- {
- return $STR(name);
- },
-
- cropString: function(text)
- {
- return cropString(text);
- },
-
- cropMultipleLines: function(text, limit)
- {
- return cropMultipleLines(text, limit);
- },
-
- toLowerCase: function(text)
- {
- return text ? text.toLowerCase() : text;
- },
-
- plural: function(n)
- {
- return n == 1 ? "" : "s";
- }
-});
-
-// ************************************************************************************************
-
-
-// ************************************************************************************************
-}});
-
-/* See license.txt for terms of usage */
-
-FBL.ns( /** @scope s_gui */ function() { with (FBL) {
-// ************************************************************************************************
-
-// ************************************************************************************************
-// Controller
-
-/**@namespace*/
-FBL.Controller = {
-
- controllers: null,
- controllerContext: null,
-
- initialize: function(context)
- {
- this.controllers = [];
- this.controllerContext = context || Firebug.chrome;
- },
-
- shutdown: function()
- {
- this.removeControllers();
-
- //this.controllers = null;
- //this.controllerContext = null;
- },
-
- addController: function()
- {
- for (var i=0, arg; arg=arguments[i]; i++)
- {
- // If the first argument is a string, make a selector query
- // within the controller node context
- if (typeof arg[0] == "string")
- {
- arg[0] = $$(arg[0], this.controllerContext);
- }
-
- // bind the handler to the proper context
- var handler = arg[2];
- arg[2] = bind(handler, this);
- // save the original handler as an extra-argument, so we can
- // look for it later, when removing a particular controller
- arg[3] = handler;
-
- this.controllers.push(arg);
- addEvent.apply(this, arg);
- }
- },
-
- removeController: function()
- {
- for (var i=0, arg; arg=arguments[i]; i++)
- {
- for (var j=0, c; c=this.controllers[j]; j++)
- {
- if (arg[0] == c[0] && arg[1] == c[1] && arg[2] == c[3])
- removeEvent.apply(this, c);
- }
- }
- },
-
- removeControllers: function()
- {
- for (var i=0, c; c=this.controllers[i]; i++)
- {
- removeEvent.apply(this, c);
- }
- }
-};
-
-
-// ************************************************************************************************
-// PanelBar
-
-/**@namespace*/
-FBL.PanelBar =
-{
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- panelMap: null,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- selectedPanel: null,
- parentPanelName: null,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- create: function(ownerPanel)
- {
- this.panelMap = {};
- this.ownerPanel = ownerPanel;
-
- if (ownerPanel)
- {
- ownerPanel.sidePanelBarNode = createElement("span");
- ownerPanel.sidePanelBarNode.style.display = "none";
- ownerPanel.sidePanelBarBoxNode.appendChild(ownerPanel.sidePanelBarNode);
- }
-
- var panels = Firebug.panelTypes;
- for (var i=0, p; p=panels[i]; i++)
- {
- if ( // normal Panel of the Chrome's PanelBar
- !ownerPanel && !p.prototype.parentPanel ||
- // Child Panel of the current Panel's SidePanelBar
- ownerPanel && p.prototype.parentPanel &&
- ownerPanel.name == p.prototype.parentPanel)
- {
- this.addPanel(p.prototype.name);
- }
- }
- },
-
- destroy: function()
- {
- PanelBar.shutdown.call(this);
-
- for (var name in this.panelMap)
- {
- this.removePanel(name);
-
- var panel = this.panelMap[name];
- panel.destroy();
-
- this.panelMap[name] = null;
- delete this.panelMap[name];
- }
-
- this.panelMap = null;
- this.ownerPanel = null;
- },
-
- initialize: function()
- {
- if (this.ownerPanel)
- this.ownerPanel.sidePanelBarNode.style.display = "inline";
-
- for(var name in this.panelMap)
- {
- (function(self, name){
-
- // tab click handler
- var onTabClick = function onTabClick()
- {
- self.selectPanel(name);
- return false;
- };
-
- Firebug.chrome.addController([self.panelMap[name].tabNode, "mousedown", onTabClick]);
-
- })(this, name);
- }
- },
-
- shutdown: function()
- {
- var selectedPanel = this.selectedPanel;
-
- if (selectedPanel)
- {
- removeClass(selectedPanel.tabNode, "fbSelectedTab");
- selectedPanel.hide();
- selectedPanel.shutdown();
- }
-
- if (this.ownerPanel)
- this.ownerPanel.sidePanelBarNode.style.display = "none";
-
- this.selectedPanel = null;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- addPanel: function(panelName, parentPanel)
- {
- var PanelType = Firebug.panelTypeMap[panelName];
- var panel = this.panelMap[panelName] = new PanelType();
-
- panel.create();
- },
-
- removePanel: function(panelName)
- {
- var panel = this.panelMap[panelName];
- if (panel.hasOwnProperty(panelName))
- panel.destroy();
- },
-
- selectPanel: function(panelName)
- {
- var selectedPanel = this.selectedPanel;
- var panel = this.panelMap[panelName];
-
- if (panel && selectedPanel != panel)
- {
- if (selectedPanel)
- {
- removeClass(selectedPanel.tabNode, "fbSelectedTab");
- selectedPanel.shutdown();
- selectedPanel.hide();
- }
-
- if (!panel.parentPanel)
- Firebug.context.persistedState.selectedPanelName = panelName;
-
- this.selectedPanel = panel;
-
- setClass(panel.tabNode, "fbSelectedTab");
- panel.show();
- panel.initialize();
- }
- },
-
- getPanel: function(panelName)
- {
- var panel = this.panelMap[panelName];
-
- return panel;
- }
-
-};
-
-//************************************************************************************************
-// Button
-
-/**
- * options.element
- * options.caption
- * options.title
- *
- * options.owner
- * options.className
- * options.pressedClassName
- *
- * options.onPress
- * options.onUnpress
- * options.onClick
- *
- * @class
- * @extends FBL.Controller
- *
- */
-
-FBL.Button = function(options)
-{
- options = options || {};
-
- append(this, options);
-
- this.state = "unpressed";
- this.display = "unpressed";
-
- if (this.element)
- {
- this.container = this.element.parentNode;
- }
- else
- {
- this.shouldDestroy = true;
-
- this.container = this.owner.getPanel().toolButtonsNode;
-
- this.element = createElement("a", {
- className: this.baseClassName + " " + this.className + " fbHover",
- innerHTML: this.caption
- });
-
- if (this.title)
- this.element.title = this.title;
-
- this.container.appendChild(this.element);
- }
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-Button.prototype = extend(Controller,
-/**@extend FBL.Button.prototype*/
-{
- type: "normal",
- caption: "caption",
- title: null,
-
- className: "", // custom class
- baseClassName: "fbButton", // control class
- pressedClassName: "fbBtnPressed", // control pressed class
-
- element: null,
- container: null,
- owner: null,
-
- state: null,
- display: null,
-
- destroy: function()
- {
- this.shutdown();
-
- // only remove if it is a dynamically generated button (not pre-rendered)
- if (this.shouldDestroy)
- this.container.removeChild(this.element);
-
- this.element = null;
- this.container = null;
- this.owner = null;
- },
-
- initialize: function()
- {
- Controller.initialize.apply(this);
-
- var element = this.element;
-
- this.addController([element, "mousedown", this.handlePress]);
-
- if (this.type == "normal")
- this.addController(
- [element, "mouseup", this.handleUnpress],
- [element, "mouseout", this.handleUnpress],
- [element, "click", this.handleClick]
- );
- },
-
- shutdown: function()
- {
- Controller.shutdown.apply(this);
- },
-
- restore: function()
- {
- this.changeState("unpressed");
- },
-
- changeState: function(state)
- {
- this.state = state;
- this.changeDisplay(state);
- },
-
- changeDisplay: function(display)
- {
- if (display != this.display)
- {
- if (display == "pressed")
- {
- setClass(this.element, this.pressedClassName);
- }
- else if (display == "unpressed")
- {
- removeClass(this.element, this.pressedClassName);
- }
- this.display = display;
- }
- },
-
- handlePress: function(event)
- {
- cancelEvent(event, true);
-
- if (this.type == "normal")
- {
- this.changeDisplay("pressed");
- this.beforeClick = true;
- }
- else if (this.type == "toggle")
- {
- if (this.state == "pressed")
- {
- this.changeState("unpressed");
-
- if (this.onUnpress)
- this.onUnpress.apply(this.owner, arguments);
- }
- else
- {
- this.changeState("pressed");
-
- if (this.onPress)
- this.onPress.apply(this.owner, arguments);
- }
-
- if (this.onClick)
- this.onClick.apply(this.owner, arguments);
- }
-
- return false;
- },
-
- handleUnpress: function(event)
- {
- cancelEvent(event, true);
-
- if (this.beforeClick)
- this.changeDisplay("unpressed");
-
- return false;
- },
-
- handleClick: function(event)
- {
- cancelEvent(event, true);
-
- if (this.type == "normal")
- {
- if (this.onClick)
- this.onClick.apply(this.owner);
-
- this.changeState("unpressed");
- }
-
- this.beforeClick = false;
-
- return false;
- }
-});
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-/**
- * @class
- * @extends FBL.Button
- */
-FBL.IconButton = function()
-{
- Button.apply(this, arguments);
-};
-
-IconButton.prototype = extend(Button.prototype,
-/**@extend FBL.IconButton.prototype*/
-{
- baseClassName: "fbIconButton",
- pressedClassName: "fbIconPressed"
-});
-
-
-//************************************************************************************************
-// Menu
-
-var menuItemProps = {"class": "$item.className", type: "$item.type", value: "$item.value",
- _command: "$item.command"};
-
-if (isIE6)
- menuItemProps.href = "javascript:void(0)";
-
-// Allow GUI to be loaded even when Domplate module is not installed.
-if (FBL.domplate)
-var MenuPlate = domplate(Firebug.Rep,
-{
- tag:
- DIV({"class": "fbMenu fbShadow"},
- DIV({"class": "fbMenuContent fbShadowContent"},
- FOR("item", "$object.items|memberIterator",
- TAG("$item.tag", {item: "$item"})
- )
- )
- ),
-
- itemTag:
- A(menuItemProps,
- "$item.label"
- ),
-
- checkBoxTag:
- A(extend(menuItemProps, {checked : "$item.checked"}),
-
- "$item.label"
- ),
-
- radioButtonTag:
- A(extend(menuItemProps, {selected : "$item.selected"}),
-
- "$item.label"
- ),
-
- groupTag:
- A(extend(menuItemProps, {child: "$item.child"}),
- "$item.label"
- ),
-
- shortcutTag:
- A(menuItemProps,
- "$item.label",
- SPAN({"class": "fbMenuShortcutKey"},
- "$item.key"
- )
- ),
-
- separatorTag:
- SPAN({"class": "fbMenuSeparator"}),
-
- memberIterator: function(items)
- {
- var result = [];
-
- for (var i=0, length=items.length; i<length; i++)
- {
- var item = items[i];
-
- // separator representation
- if (typeof item == "string" && item.indexOf("-") == 0)
- {
- result.push({tag: this.separatorTag});
- continue;
- }
-
- item = extend(item, {});
-
- item.type = item.type || "";
- item.value = item.value || "";
-
- var type = item.type;
-
- // default item representation
- item.tag = this.itemTag;
-
- var className = item.className || "";
-
- className += "fbMenuOption fbHover ";
-
- // specific representations
- if (type == "checkbox")
- {
- className += "fbMenuCheckBox ";
- item.tag = this.checkBoxTag;
- }
- else if (type == "radiobutton")
- {
- className += "fbMenuRadioButton ";
- item.tag = this.radioButtonTag;
- }
- else if (type == "group")
- {
- className += "fbMenuGroup ";
- item.tag = this.groupTag;
- }
- else if (type == "shortcut")
- {
- className += "fbMenuShortcut ";
- item.tag = this.shortcutTag;
- }
-
- if (item.checked)
- className += "fbMenuChecked ";
- else if (item.selected)
- className += "fbMenuRadioSelected ";
-
- if (item.disabled)
- className += "fbMenuDisabled ";
-
- item.className = className;
-
- item.label = $STR(item.label);
-
- result.push(item);
- }
-
- return result;
- }
-});
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-/**
- * options
- * options.element
- * options.id
- * options.items
- *
- * item.label
- * item.className
- * item.type
- * item.value
- * item.disabled
- * item.checked
- * item.selected
- * item.command
- * item.child
- *
- *
- * @class
- * @extends FBL.Controller
- *
- */
-FBL.Menu = function(options)
-{
- // if element is not pre-rendered, we must render it now
- if (!options.element)
- {
- if (options.getItems)
- options.items = options.getItems();
-
- options.element = MenuPlate.tag.append(
- {object: options},
- getElementByClass(Firebug.chrome.document, "fbBody"),
- MenuPlate
- );
- }
-
- // extend itself with the provided options
- append(this, options);
-
- if (typeof this.element == "string")
- {
- this.id = this.element;
- this.element = $(this.id);
- }
- else if (this.id)
- {
- this.element.id = this.id;
- }
-
- this.element.firebugIgnore = true;
- this.elementStyle = this.element.style;
-
- this.isVisible = false;
-
- this.handleMouseDown = bind(this.handleMouseDown, this);
- this.handleMouseOver = bind(this.handleMouseOver, this);
- this.handleMouseOut = bind(this.handleMouseOut, this);
-
- this.handleWindowMouseDown = bind(this.handleWindowMouseDown, this);
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var menuMap = {};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-Menu.prototype = extend(Controller,
-/**@extend FBL.Menu.prototype*/
-{
- destroy: function()
- {
- //if (this.element) console.log("destroy", this.element.id);
-
- this.hide();
-
- // if it is a childMenu, remove its reference from the parentMenu
- if (this.parentMenu)
- this.parentMenu.childMenu = null;
-
- // remove the element from the document
- this.element.parentNode.removeChild(this.element);
-
- // clear references
- this.element = null;
- this.elementStyle = null;
- this.parentMenu = null;
- this.parentTarget = null;
- },
-
- initialize: function()
- {
- Controller.initialize.call(this);
-
- this.addController(
- [this.element, "mousedown", this.handleMouseDown],
- [this.element, "mouseover", this.handleMouseOver]
- );
- },
-
- shutdown: function()
- {
- Controller.shutdown.call(this);
- },
-
- show: function(x, y)
- {
- this.initialize();
-
- if (this.isVisible) return;
-
- //console.log("show", this.element.id);
-
- x = x || 0;
- y = y || 0;
-
- if (this.parentMenu)
- {
- var oldChildMenu = this.parentMenu.childMenu;
- if (oldChildMenu && oldChildMenu != this)
- {
- oldChildMenu.destroy();
- }
-
- this.parentMenu.childMenu = this;
- }
- else
- addEvent(Firebug.chrome.document, "mousedown", this.handleWindowMouseDown);
-
- this.elementStyle.display = "block";
- this.elementStyle.visibility = "hidden";
-
- var size = Firebug.chrome.getSize();
-
- x = Math.min(x, size.width - this.element.clientWidth - 10);
- x = Math.max(x, 0);
-
- y = Math.min(y, size.height - this.element.clientHeight - 10);
- y = Math.max(y, 0);
-
- this.elementStyle.left = x + "px";
- this.elementStyle.top = y + "px";
-
- this.elementStyle.visibility = "visible";
-
- this.isVisible = true;
-
- if (isFunction(this.onShow))
- this.onShow.apply(this, arguments);
- },
-
- hide: function()
- {
- this.clearHideTimeout();
- this.clearShowChildTimeout();
-
- if (!this.isVisible) return;
-
- //console.log("hide", this.element.id);
-
- this.elementStyle.display = "none";
-
- if(this.childMenu)
- {
- this.childMenu.destroy();
- this.childMenu = null;
- }
-
- if(this.parentTarget)
- removeClass(this.parentTarget, "fbMenuGroupSelected");
-
- this.isVisible = false;
-
- this.shutdown();
-
- if (isFunction(this.onHide))
- this.onHide.apply(this, arguments);
- },
-
- showChildMenu: function(target)
- {
- var id = target.getAttribute("child");
-
- var parent = this;
- var target = target;
-
- this.showChildTimeout = Firebug.chrome.window.setTimeout(function(){
-
- //if (!parent.isVisible) return;
-
- var box = Firebug.chrome.getElementBox(target);
-
- var childMenuObject = menuMap.hasOwnProperty(id) ?
- menuMap[id] : {element: $(id)};
-
- var childMenu = new Menu(extend(childMenuObject,
- {
- parentMenu: parent,
- parentTarget: target
- }));
-
- var offsetLeft = isIE6 ? -1 : -6; // IE6 problem with fixed position
- childMenu.show(box.left + box.width + offsetLeft, box.top -6);
- setClass(target, "fbMenuGroupSelected");
-
- },350);
- },
-
- clearHideTimeout: function()
- {
- if (this.hideTimeout)
- {
- Firebug.chrome.window.clearTimeout(this.hideTimeout);
- delete this.hideTimeout;
- }
- },
-
- clearShowChildTimeout: function()
- {
- if(this.showChildTimeout)
- {
- Firebug.chrome.window.clearTimeout(this.showChildTimeout);
- this.showChildTimeout = null;
- }
- },
-
- handleMouseDown: function(event)
- {
- cancelEvent(event, true);
-
- var topParent = this;
- while (topParent.parentMenu)
- topParent = topParent.parentMenu;
-
- var target = event.target || event.srcElement;
-
- target = getAncestorByClass(target, "fbMenuOption");
-
- if(!target || hasClass(target, "fbMenuGroup"))
- return false;
-
- if (target && !hasClass(target, "fbMenuDisabled"))
- {
- var type = target.getAttribute("type");
-
- if (type == "checkbox")
- {
- var checked = target.getAttribute("checked");
- var value = target.getAttribute("value");
- var wasChecked = hasClass(target, "fbMenuChecked");
-
- if (wasChecked)
- {
- removeClass(target, "fbMenuChecked");
- target.setAttribute("checked", "");
- }
- else
- {
- setClass(target, "fbMenuChecked");
- target.setAttribute("checked", "true");
- }
-
- if (isFunction(this.onCheck))
- this.onCheck.call(this, target, value, !wasChecked);
- }
-
- if (type == "radiobutton")
- {
- var selectedRadios = getElementsByClass(target.parentNode, "fbMenuRadioSelected");
-
- var group = target.getAttribute("group");
-
- for (var i = 0, length = selectedRadios.length; i < length; i++)
- {
- radio = selectedRadios[i];
-
- if (radio.getAttribute("group") == group)
- {
- removeClass(radio, "fbMenuRadioSelected");
- radio.setAttribute("selected", "");
- }
- }
-
- setClass(target, "fbMenuRadioSelected");
- target.setAttribute("selected", "true");
- }
-
- var handler = null;
-
- // target.command can be a function or a string.
- var cmd = target.command;
-
- // If it is a function it will be used as the handler
- if (isFunction(cmd))
- handler = cmd;
- // If it is a string it the property of the current menu object
- // will be used as the handler
- else if (typeof cmd == "string")
- handler = this[cmd];
-
- var closeMenu = true;
-
- if (handler)
- closeMenu = handler.call(this, target) !== false;
-
- if (closeMenu)
- topParent.hide();
- }
-
- return false;
- },
-
- handleWindowMouseDown: function(event)
- {
- //console.log("handleWindowMouseDown");
-
- var target = event.target || event.srcElement;
-
- target = getAncestorByClass(target, "fbMenu");
-
- if (!target)
- {
- removeEvent(Firebug.chrome.document, "mousedown", this.handleWindowMouseDown);
- this.hide();
- }
- },
-
- handleMouseOver: function(event)
- {
- //console.log("handleMouseOver", this.element.id);
-
- this.clearHideTimeout();
- this.clearShowChildTimeout();
-
- var target = event.target || event.srcElement;
-
- target = getAncestorByClass(target, "fbMenuOption");
-
- if(!target)
- return;
-
- var childMenu = this.childMenu;
- if(childMenu)
- {
- removeClass(childMenu.parentTarget, "fbMenuGroupSelected");
-
- if (childMenu.parentTarget != target && childMenu.isVisible)
- {
- childMenu.clearHideTimeout();
- childMenu.hideTimeout = Firebug.chrome.window.setTimeout(function(){
- childMenu.destroy();
- },300);
- }
- }
-
- if(hasClass(target, "fbMenuGroup"))
- {
- this.showChildMenu(target);
- }
- }
-});
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-append(Menu,
-/**@extend FBL.Menu*/
-{
- register: function(object)
- {
- menuMap[object.id] = object;
- },
-
- check: function(element)
- {
- setClass(element, "fbMenuChecked");
- element.setAttribute("checked", "true");
- },
-
- uncheck: function(element)
- {
- removeClass(element, "fbMenuChecked");
- element.setAttribute("checked", "");
- },
-
- disable: function(element)
- {
- setClass(element, "fbMenuDisabled");
- },
-
- enable: function(element)
- {
- removeClass(element, "fbMenuDisabled");
- }
-});
-
-
-//************************************************************************************************
-// Status Bar
-
-/**@class*/
-function StatusBar(){};
-
-StatusBar.prototype = extend(Controller, {
-
-});
-
-// ************************************************************************************************
-
-
-// ************************************************************************************************
-}});
-
-/* See license.txt for terms of usage */
-
-FBL.ns( /**@scope s_context*/ function() { with (FBL) {
-// ************************************************************************************************
-
-// ************************************************************************************************
-// Globals
-
-var refreshDelay = 300;
-
-// Opera and some versions of webkit returns the wrong value of document.elementFromPoint()
-// function, without taking into account the scroll position. Safari 4 (webkit/531.21.8)
-// still have this issue. Google Chrome 4 (webkit/532.5) does not. So, we're assuming this
-// issue was fixed in the 532 version
-var shouldFixElementFromPoint = isOpera || isSafari && browserVersion < "532";
-
-var evalError = "___firebug_evaluation_error___";
-var pixelsPerInch;
-
-var resetStyle = "margin:0; padding:0; border:0; position:absolute; overflow:hidden; display:block;";
-var offscreenStyle = resetStyle + "top:-1234px; left:-1234px;";
-
-
-// ************************************************************************************************
-// Context
-
-/** @class */
-FBL.Context = function(win)
-{
- this.window = win.window;
- this.document = win.document;
-
- this.browser = Env.browser;
-
- // Some windows in IE, like iframe, doesn't have the eval() method
- if (isIE && !this.window.eval)
- {
- // But after executing the following line the method magically appears!
- this.window.execScript("null");
- // Just to make sure the "magic" really happened
- if (!this.window.eval)
- throw new Error("Firebug Error: eval() method not found in this window");
- }
-
- // Create a new "black-box" eval() method that runs in the global namespace
- // of the context window, without exposing the local variables declared
- // by the function that calls it
- this.eval = this.window.eval("new Function('" +
- "try{ return window.eval.apply(window,arguments) }catch(E){ E."+evalError+"=true; return E }" +
- "')");
-};
-
-FBL.Context.prototype =
-{
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // partial-port of Firebug tabContext.js
-
- browser: null,
- loaded: true,
-
- setTimeout: function(fn, delay)
- {
- var win = this.window;
-
- if (win.setTimeout == this.setTimeout)
- throw new Error("setTimeout recursion");
-
- var timeout = win.setTimeout.apply ? // IE doesn't have apply method on setTimeout
- win.setTimeout.apply(win, arguments) :
- win.setTimeout(fn, delay);
-
- if (!this.timeouts)
- this.timeouts = {};
-
- this.timeouts[timeout] = 1;
-
- return timeout;
- },
-
- clearTimeout: function(timeout)
- {
- clearTimeout(timeout);
-
- if (this.timeouts)
- delete this.timeouts[timeout];
- },
-
- setInterval: function(fn, delay)
- {
- var win = this.window;
-
- var timeout = win.setInterval.apply ? // IE doesn't have apply method on setTimeout
- win.setInterval.apply(win, arguments) :
- win.setInterval(fn, delay);
-
- if (!this.intervals)
- this.intervals = {};
-
- this.intervals[timeout] = 1;
-
- return timeout;
- },
-
- clearInterval: function(timeout)
- {
- clearInterval(timeout);
-
- if (this.intervals)
- delete this.intervals[timeout];
- },
-
- invalidatePanels: function()
- {
- if (!this.invalidPanels)
- this.invalidPanels = {};
-
- for (var i = 0; i < arguments.length; ++i)
- {
- var panelName = arguments[i];
-
- // avoid error. need to create a better getPanel() function as explained below
- if (!Firebug.chrome || !Firebug.chrome.selectedPanel)
- return;
-
- //var panel = this.getPanel(panelName, true);
- //TODO: xxxpedro context how to get all panels using a single function?
- // the current workaround to make the invalidation works is invalidating
- // only sidePanels. There's also a problem with panel name (LowerCase in Firebug Lite)
- var panel = Firebug.chrome.selectedPanel.sidePanelBar ?
- Firebug.chrome.selectedPanel.sidePanelBar.getPanel(panelName, true) :
- null;
-
- if (panel && !panel.noRefresh)
- this.invalidPanels[panelName] = 1;
- }
-
- if (this.refreshTimeout)
- {
- this.clearTimeout(this.refreshTimeout);
- delete this.refreshTimeout;
- }
-
- this.refreshTimeout = this.setTimeout(bindFixed(function()
- {
- var invalids = [];
-
- for (var panelName in this.invalidPanels)
- {
- //var panel = this.getPanel(panelName, true);
- //TODO: xxxpedro context how to get all panels using a single function?
- // the current workaround to make the invalidation works is invalidating
- // only sidePanels. There's also a problem with panel name (LowerCase in Firebug Lite)
- var panel = Firebug.chrome.selectedPanel.sidePanelBar ?
- Firebug.chrome.selectedPanel.sidePanelBar.getPanel(panelName, true) :
- null;
-
- if (panel)
- {
- if (panel.visible && !panel.editing)
- panel.refresh();
- else
- panel.needsRefresh = true;
-
- // If the panel is being edited, we'll keep trying to
- // refresh it until editing is done
- if (panel.editing)
- invalids.push(panelName);
- }
- }
-
- delete this.invalidPanels;
- delete this.refreshTimeout;
-
- // Keep looping until every tab is valid
- if (invalids.length)
- this.invalidatePanels.apply(this, invalids);
- }, this), refreshDelay);
- },
-
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Evalutation Method
-
- /**
- * Evaluates an expression in the current context window.
- *
- * @param {String} expr expression to be evaluated
- *
- * @param {String} context string indicating the global location
- * of the object that will be used as the
- * context. The context is referred in
- * the expression as the "this" keyword.
- * If no context is informed, the "window"
- * context is used.
- *
- * @param {String} api string indicating the global location
- * of the object that will be used as the
- * api of the evaluation.
- *
- * @param {Function} errorHandler(message) error handler to be called
- * if the evaluation fails.
- */
- evaluate: function(expr, context, api, errorHandler)
- {
- // the default context is the "window" object. It can be any string that represents
- // a global accessible element as: "my.namespaced.object"
- context = context || "window";
-
- var isObjectLiteral = trim(expr).indexOf("{") == 0,
- cmd,
- result;
-
- // if the context is the "window" object, we don't need a closure
- if (context == "window")
- {
- // If it is an object literal, then wrap the expression with parenthesis so we can
- // capture the return value
- if (isObjectLiteral)
- {
- cmd = api ?
- "with("+api+"){ ("+expr+") }" :
- "(" + expr + ")";
- }
- else
- {
- cmd = api ?
- "with("+api+"){ "+expr+" }" :
- expr;
- }
- }
- else
- {
- cmd = api ?
- // with API and context, no return value
- "(function(arguments){ with(" + api + "){ " +
- expr +
- " } }).call(" + context + ",undefined)"
- :
- // with context only, no return value
- "(function(arguments){ " +
- expr +
- " }).call(" + context + ",undefined)";
- }
-
- result = this.eval(cmd);
-
- if (result && result[evalError])
- {
- var msg = result.name ? (result.name + ": ") : "";
- msg += result.message || result;
-
- if (errorHandler)
- result = errorHandler(msg);
- else
- result = msg;
- }
-
- return result;
- },
-
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Window Methods
-
- getWindowSize: function()
- {
- var width=0, height=0, el;
-
- if (typeof this.window.innerWidth == "number")
- {
- width = this.window.innerWidth;
- height = this.window.innerHeight;
- }
- else if ((el=this.document.documentElement) && (el.clientHeight || el.clientWidth))
- {
- width = el.clientWidth;
- height = el.clientHeight;
- }
- else if ((el=this.document.body) && (el.clientHeight || el.clientWidth))
- {
- width = el.clientWidth;
- height = el.clientHeight;
- }
-
- return {width: width, height: height};
- },
-
- getWindowScrollSize: function()
- {
- var width=0, height=0, el;
-
- // first try the document.documentElement scroll size
- if (!isIEQuiksMode && (el=this.document.documentElement) &&
- (el.scrollHeight || el.scrollWidth))
- {
- width = el.scrollWidth;
- height = el.scrollHeight;
- }
-
- // then we need to check if document.body has a bigger scroll size value
- // because sometimes depending on the browser and the page, the document.body
- // scroll size returns a smaller (and wrong) measure
- if ((el=this.document.body) && (el.scrollHeight || el.scrollWidth) &&
- (el.scrollWidth > width || el.scrollHeight > height))
- {
- width = el.scrollWidth;
- height = el.scrollHeight;
- }
-
- return {width: width, height: height};
- },
-
- getWindowScrollPosition: function()
- {
- var top=0, left=0, el;
-
- if(typeof this.window.pageYOffset == "number")
- {
- top = this.window.pageYOffset;
- left = this.window.pageXOffset;
- }
- else if((el=this.document.body) && (el.scrollTop || el.scrollLeft))
- {
- top = el.scrollTop;
- left = el.scrollLeft;
- }
- else if((el=this.document.documentElement) && (el.scrollTop || el.scrollLeft))
- {
- top = el.scrollTop;
- left = el.scrollLeft;
- }
-
- return {top:top, left:left};
- },
-
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Element Methods
-
- getElementFromPoint: function(x, y)
- {
- if (shouldFixElementFromPoint)
- {
- var scroll = this.getWindowScrollPosition();
- return this.document.elementFromPoint(x + scroll.left, y + scroll.top);
- }
- else
- return this.document.elementFromPoint(x, y);
- },
-
- getElementPosition: function(el)
- {
- var left = 0;
- var top = 0;
-
- do
- {
- left += el.offsetLeft;
- top += el.offsetTop;
- }
- while (el = el.offsetParent);
-
- return {left:left, top:top};
- },
-
- getElementBox: function(el)
- {
- var result = {};
-
- if (el.getBoundingClientRect)
- {
- var rect = el.getBoundingClientRect();
-
- // fix IE problem with offset when not in fullscreen mode
- var offset = isIE ? this.document.body.clientTop || this.document.documentElement.clientTop: 0;
-
- var scroll = this.getWindowScrollPosition();
-
- result.top = Math.round(rect.top - offset + scroll.top);
- result.left = Math.round(rect.left - offset + scroll.left);
- result.height = Math.round(rect.bottom - rect.top);
- result.width = Math.round(rect.right - rect.left);
- }
- else
- {
- var position = this.getElementPosition(el);
-
- result.top = position.top;
- result.left = position.left;
- result.height = el.offsetHeight;
- result.width = el.offsetWidth;
- }
-
- return result;
- },
-
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Measurement Methods
-
- getMeasurement: function(el, name)
- {
- var result = {value: 0, unit: "px"};
-
- var cssValue = this.getStyle(el, name);
-
- if (!cssValue) return result;
- if (cssValue.toLowerCase() == "auto") return result;
-
- var reMeasure = /(\d+\.?\d*)(.*)/;
- var m = cssValue.match(reMeasure);
-
- if (m)
- {
- result.value = m[1]-0;
- result.unit = m[2].toLowerCase();
- }
-
- return result;
- },
-
- getMeasurementInPixels: function(el, name)
- {
- if (!el) return null;
-
- var m = this.getMeasurement(el, name);
- var value = m.value;
- var unit = m.unit;
-
- if (unit == "px")
- return value;
-
- else if (unit == "pt")
- return this.pointsToPixels(name, value);
-
- else if (unit == "em")
- return this.emToPixels(el, value);
-
- else if (unit == "%")
- return this.percentToPixels(el, value);
-
- else if (unit == "ex")
- return this.exToPixels(el, value);
-
- // TODO: add other units. Maybe create a better general way
- // to calculate measurements in different units.
- },
-
- getMeasurementBox1: function(el, name)
- {
- var sufixes = ["Top", "Left", "Bottom", "Right"];
- var result = [];
-
- for(var i=0, sufix; sufix=sufixes[i]; i++)
- result[i] = Math.round(this.getMeasurementInPixels(el, name + sufix));
-
- return {top:result[0], left:result[1], bottom:result[2], right:result[3]};
- },
-
- getMeasurementBox: function(el, name)
- {
- var result = [];
- var sufixes = name == "border" ?
- ["TopWidth", "LeftWidth", "BottomWidth", "RightWidth"] :
- ["Top", "Left", "Bottom", "Right"];
-
- if (isIE)
- {
- var propName, cssValue;
- var autoMargin = null;
-
- for(var i=0, sufix; sufix=sufixes[i]; i++)
- {
- propName = name + sufix;
-
- cssValue = el.currentStyle[propName] || el.style[propName];
-
- if (cssValue == "auto")
- {
- if (!autoMargin)
- autoMargin = this.getCSSAutoMarginBox(el);
-
- result[i] = autoMargin[sufix.toLowerCase()];
- }
- else
- result[i] = this.getMeasurementInPixels(el, propName);
-
- }
-
- }
- else
- {
- for(var i=0, sufix; sufix=sufixes[i]; i++)
- result[i] = this.getMeasurementInPixels(el, name + sufix);
- }
-
- return {top:result[0], left:result[1], bottom:result[2], right:result[3]};
- },
-
- getCSSAutoMarginBox: function(el)
- {
- if (isIE && " meta title input script link a ".indexOf(" "+el.nodeName.toLowerCase()+" ") != -1)
- return {top:0, left:0, bottom:0, right:0};
- /**/
-
- if (isIE && " h1 h2 h3 h4 h5 h6 h7 ul p ".indexOf(" "+el.nodeName.toLowerCase()+" ") == -1)
- return {top:0, left:0, bottom:0, right:0};
- /**/
-
- var offsetTop = 0;
- if (false && isIEStantandMode)
- {
- var scrollSize = Firebug.browser.getWindowScrollSize();
- offsetTop = scrollSize.height;
- }
-
- var box = this.document.createElement("div");
- //box.style.cssText = "margin:0; padding:1px; border: 0; position:static; overflow:hidden; visibility: hidden;";
- box.style.cssText = "margin:0; padding:1px; border: 0; visibility: hidden;";
-
- var clone = el.cloneNode(false);
- var text = this.document.createTextNode("&nbsp;");
- clone.appendChild(text);
-
- box.appendChild(clone);
-
- this.document.body.appendChild(box);
-
- var marginTop = clone.offsetTop - box.offsetTop - 1;
- var marginBottom = box.offsetHeight - clone.offsetHeight - 2 - marginTop;
-
- var marginLeft = clone.offsetLeft - box.offsetLeft - 1;
- var marginRight = box.offsetWidth - clone.offsetWidth - 2 - marginLeft;
-
- this.document.body.removeChild(box);
-
- return {top:marginTop+offsetTop, left:marginLeft, bottom:marginBottom-offsetTop, right:marginRight};
- },
-
- getFontSizeInPixels: function(el)
- {
- var size = this.getMeasurement(el, "fontSize");
-
- if (size.unit == "px") return size.value;
-
- // get font size, the dirty way
- var computeDirtyFontSize = function(el, calibration)
- {
- var div = this.document.createElement("div");
- var divStyle = offscreenStyle;
-
- if (calibration)
- divStyle += " font-size:"+calibration+"px;";
-
- div.style.cssText = divStyle;
- div.innerHTML = "A";
- el.appendChild(div);
-
- var value = div.offsetHeight;
- el.removeChild(div);
- return value;
- };
-
- /*
- var calibrationBase = 200;
- var calibrationValue = computeDirtyFontSize(el, calibrationBase);
- var rate = calibrationBase / calibrationValue;
- /**/
-
- // the "dirty technique" fails in some environments, so we're using a static value
- // based in some tests.
- var rate = 200 / 225;
-
- var value = computeDirtyFontSize(el);
-
- return value * rate;
- },
-
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Unit Funtions
-
- pointsToPixels: function(name, value, returnFloat)
- {
- var axis = /Top$|Bottom$/.test(name) ? "y" : "x";
-
- var result = value * pixelsPerInch[axis] / 72;
-
- return returnFloat ? result : Math.round(result);
- },
-
- emToPixels: function(el, value)
- {
- if (!el) return null;
-
- var fontSize = this.getFontSizeInPixels(el);
-
- return Math.round(value * fontSize);
- },
-
- exToPixels: function(el, value)
- {
- if (!el) return null;
-
- // get ex value, the dirty way
- var div = this.document.createElement("div");
- div.style.cssText = offscreenStyle + "width:"+value + "ex;";
-
- el.appendChild(div);
- var value = div.offsetWidth;
- el.removeChild(div);
-
- return value;
- },
-
- percentToPixels: function(el, value)
- {
- if (!el) return null;
-
- // get % value, the dirty way
- var div = this.document.createElement("div");
- div.style.cssText = offscreenStyle + "width:"+value + "%;";
-
- el.appendChild(div);
- var value = div.offsetWidth;
- el.removeChild(div);
-
- return value;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- getStyle: isIE ? function(el, name)
- {
- return el.currentStyle[name] || el.style[name] || undefined;
- }
- : function(el, name)
- {
- return this.document.defaultView.getComputedStyle(el,null)[name]
- || el.style[name] || undefined;
- }
-
-};
-
-
-// ************************************************************************************************
-}});
-
-/* See license.txt for terms of usage */
-
-FBL.ns( /**@scope ns-chrome*/ function() { with (FBL) {
-// ************************************************************************************************
-
-// ************************************************************************************************
-// Globals
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// Window Options
-
-var WindowDefaultOptions =
- {
- type: "frame",
- id: "FirebugUI"
- //height: 350 // obsolete
- },
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// Instantiated objects
-
- commandLine,
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// Interface Elements Cache
-
- fbTop,
- fbContent,
- fbContentStyle,
- fbBottom,
- fbBtnInspect,
-
- fbToolbar,
-
- fbPanelBox1,
- fbPanelBox1Style,
- fbPanelBox2,
- fbPanelBox2Style,
- fbPanelBar2Box,
- fbPanelBar2BoxStyle,
-
- fbHSplitter,
- fbVSplitter,
- fbVSplitterStyle,
-
- fbPanel1,
- fbPanel1Style,
- fbPanel2,
- fbPanel2Style,
-
- fbConsole,
- fbConsoleStyle,
- fbHTML,
-
- fbCommandLine,
- fbLargeCommandLine,
- fbLargeCommandButtons,
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// Cached size values
-
- topHeight,
- topPartialHeight,
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- chromeRedrawSkipRate = isIE ? 75 : isOpera ? 80 : 75,
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- lastSelectedPanelName,
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- focusCommandLineState = 0,
- lastFocusedPanelName,
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- lastHSplitterMouseMove = 0,
- onHSplitterMouseMoveBuffer = null,
- onHSplitterMouseMoveTimer = null,
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- lastVSplitterMouseMove = 0;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-
-// ************************************************************************************************
-// FirebugChrome
-
-FBL.defaultPersistedState =
-{
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- isOpen: false,
- height: 300,
- sidePanelWidth: 350,
-
- selectedPanelName: "Console",
- selectedHTMLElementId: null,
-
- htmlSelectionStack: []
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-};
-
-/**@namespace*/
-FBL.FirebugChrome =
-{
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- //isOpen: false,
- //height: 300,
- //sidePanelWidth: 350,
-
- //selectedPanelName: "Console",
- //selectedHTMLElementId: null,
-
- chromeMap: {},
-
- htmlSelectionStack: [],
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- create: function()
- {
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FirebugChrome.create", "creating chrome window");
-
- createChromeWindow();
- },
-
- initialize: function()
- {
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FirebugChrome.initialize", "initializing chrome window");
-
- if (Env.chrome.type == "frame" || Env.chrome.type == "div")
- ChromeMini.create(Env.chrome);
-
- var chrome = Firebug.chrome = new Chrome(Env.chrome);
- FirebugChrome.chromeMap[chrome.type] = chrome;
-
- addGlobalEvent("keydown", onGlobalKeyDown);
-
- if (Env.Options.enablePersistent && chrome.type == "popup")
- {
- // TODO: xxxpedro persist - revise chrome synchronization when in persistent mode
- var frame = FirebugChrome.chromeMap.frame;
- if (frame)
- frame.close();
-
- //chrome.reattach(frame, chrome);
- //TODO: xxxpedro persist synchronize?
- chrome.initialize();
- }
- },
-
- clone: function(FBChrome)
- {
- for (var name in FBChrome)
- {
- var prop = FBChrome[name];
- if (FBChrome.hasOwnProperty(name) && !isFunction(prop))
- {
- this[name] = prop;
- }
- }
- }
-};
-
-
-
-// ************************************************************************************************
-// Chrome Window Creation
-
-var createChromeWindow = function(options)
-{
- options = extend(WindowDefaultOptions, options || {});
-
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Locals
-
- var browserWin = Env.browser.window;
- var browserContext = new Context(browserWin);
- var prefs = Store.get("FirebugLite");
- var persistedState = prefs && prefs.persistedState || defaultPersistedState;
-
- var chrome = {},
-
- context = options.context || Env.browser,
-
- type = chrome.type = Env.Options.enablePersistent ?
- "popup" :
- options.type,
-
- isChromeFrame = type == "frame",
-
- useLocalSkin = Env.useLocalSkin,
-
- url = useLocalSkin ?
- Env.Location.skin :
- "about:blank",
-
- // document.body not available in XML+XSL documents in Firefox
- body = context.document.getElementsByTagName("body")[0],
-
- formatNode = function(node)
- {
- if (!Env.isDebugMode)
- {
- node.firebugIgnore = true;
- }
-
- var browserWinSize = browserContext.getWindowSize();
- var height = persistedState.height || 300;
-
- height = Math.min(browserWinSize.height, height);
- height = Math.max(200, height);
-
- node.style.border = "0";
- node.style.visibility = "hidden";
- node.style.zIndex = "2147483647"; // MAX z-index = 2147483647
- node.style.position = noFixedPosition ? "absolute" : "fixed";
- node.style.width = "100%"; // "102%"; IE auto margin bug
- node.style.left = "0";
- node.style.bottom = noFixedPosition ? "-1px" : "0";
- node.style.height = height + "px";
-
- // avoid flickering during chrome rendering
- //if (isFirefox)
- // node.style.display = "none";
- },
-
- createChromeDiv = function()
- {
- //Firebug.Console.warn("Firebug Lite GUI is working in 'windowless mode'. It may behave slower and receive interferences from the page in which it is installed.");
-
- var node = chrome.node = createGlobalElement("div"),
- style = createGlobalElement("style"),
-
- css = FirebugChrome.Skin.CSS
- /*
- .replace(/;/g, " !important;")
- .replace(/!important\s!important/g, "!important")
- .replace(/display\s*:\s*(\w+)\s*!important;/g, "display:$1;")*/,
-
- // reset some styles to minimize interference from the main page's style
- rules = ".fbBody *{margin:0;padding:0;font-size:11px;line-height:13px;color:inherit;}" +
- // load the chrome styles
- css +
- // adjust some remaining styles
- ".fbBody #fbHSplitter{position:absolute !important;} .fbBody #fbHTML span{line-height:14px;} .fbBody .lineNo div{line-height:inherit !important;}";
- /*
- if (isIE)
- {
- // IE7 CSS bug (FbChrome table bigger than its parent div)
- rules += ".fbBody table.fbChrome{position: static !important;}";
- }/**/
-
- style.type = "text/css";
-
- if (style.styleSheet)
- style.styleSheet.cssText = rules;
- else
- style.appendChild(context.document.createTextNode(rules));
-
- document.getElementsByTagName("head")[0].appendChild(style);
-
- node.className = "fbBody";
- node.style.overflow = "hidden";
- node.innerHTML = getChromeDivTemplate();
-
- if (isIE)
- {
- // IE7 CSS bug (FbChrome table bigger than its parent div)
- setTimeout(function(){
- node.firstChild.style.height = "1px";
- node.firstChild.style.position = "static";
- },0);
- /**/
- }
-
- formatNode(node);
-
- body.appendChild(node);
-
- chrome.window = window;
- chrome.document = document;
- onChromeLoad(chrome);
- };
-
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- try
- {
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // create the Chrome as a "div" (windowless mode)
- if (type == "div")
- {
- createChromeDiv();
- return;
- }
-
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // cretate the Chrome as an "iframe"
- else if (isChromeFrame)
- {
- // Create the Chrome Frame
- var node = chrome.node = createGlobalElement("iframe");
- node.setAttribute("src", url);
- node.setAttribute("frameBorder", "0");
-
- formatNode(node);
-
- body.appendChild(node);
-
- // must set the id after appending to the document, otherwise will cause an
- // strange error in IE, making the iframe load the page in which the bookmarklet
- // was created (like getfirebug.com), before loading the injected UI HTML,
- // generating an "Access Denied" error.
- node.id = options.id;
- }
-
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // create the Chrome as a "popup"
- else
- {
- var height = persistedState.popupHeight || 300;
- var browserWinSize = browserContext.getWindowSize();
-
- var browserWinLeft = typeof browserWin.screenX == "number" ?
- browserWin.screenX : browserWin.screenLeft;
-
- var popupLeft = typeof persistedState.popupLeft == "number" ?
- persistedState.popupLeft : browserWinLeft;
-
- var browserWinTop = typeof browserWin.screenY == "number" ?
- browserWin.screenY : browserWin.screenTop;
-
- var popupTop = typeof persistedState.popupTop == "number" ?
- persistedState.popupTop :
- Math.max(
- 0,
- Math.min(
- browserWinTop + browserWinSize.height - height,
- // Google Chrome bug
- screen.availHeight - height - 61
- )
- );
-
- var popupWidth = typeof persistedState.popupWidth == "number" ?
- persistedState.popupWidth :
- Math.max(
- 0,
- Math.min(
- browserWinSize.width,
- // Opera opens popup in a new tab if it's too big!
- screen.availWidth-10
- )
- );
-
- var popupHeight = typeof persistedState.popupHeight == "number" ?
- persistedState.popupHeight : 300;
-
- var options = [
- "true,top=", popupTop,
- ",left=", popupLeft,
- ",height=", popupHeight,
- ",width=", popupWidth,
- ",resizable"
- ].join(""),
-
- node = chrome.node = context.window.open(
- url,
- "popup",
- options
- );
-
- if (node)
- {
- try
- {
- node.focus();
- }
- catch(E)
- {
- alert("Firebug Error: Firebug popup was blocked.");
- return;
- }
- }
- else
- {
- alert("Firebug Error: Firebug popup was blocked.");
- return;
- }
- }
-
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Inject the interface HTML if it is not using the local skin
-
- if (!useLocalSkin)
- {
- var tpl = getChromeTemplate(!isChromeFrame),
- doc = isChromeFrame ? node.contentWindow.document : node.document;
-
- doc.write(tpl);
- doc.close();
- }
-
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Wait the Window to be loaded
-
- var win,
-
- waitDelay = useLocalSkin ? isChromeFrame ? 200 : 300 : 100,
-
- waitForWindow = function()
- {
- if ( // Frame loaded... OR
- isChromeFrame && (win=node.contentWindow) &&
- node.contentWindow.document.getElementById("fbCommandLine") ||
-
- // Popup loaded
- !isChromeFrame && (win=node.window) && node.document &&
- node.document.getElementById("fbCommandLine") )
- {
- chrome.window = win.window;
- chrome.document = win.document;
-
- // Prevent getting the wrong chrome height in FF when opening a popup
- setTimeout(function(){
- onChromeLoad(chrome);
- }, useLocalSkin ? 200 : 0);
- }
- else
- setTimeout(waitForWindow, waitDelay);
- };
-
- waitForWindow();
- }
- catch(e)
- {
- var msg = e.message || e;
-
- if (/access/i.test(msg))
- {
- // Firebug Lite could not create a window for its Graphical User Interface due to
- // a access restriction. This happens in some pages, when loading via bookmarklet.
- // In such cases, the only way is to load the GUI in a "windowless mode".
-
- if (isChromeFrame)
- body.removeChild(node);
- else if(type == "popup")
- node.close();
-
- // Load the GUI in a "windowless mode"
- createChromeDiv();
- }
- else
- {
- alert("Firebug Error: Firebug GUI could not be created.");
- }
- }
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var onChromeLoad = function onChromeLoad(chrome)
-{
- Env.chrome = chrome;
-
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Chrome onChromeLoad", "chrome window loaded");
-
- if (Env.Options.enablePersistent)
- {
- // TODO: xxxpedro persist - make better chrome synchronization when in persistent mode
- Env.FirebugChrome = FirebugChrome;
-
- chrome.window.Firebug = chrome.window.Firebug || {};
- chrome.window.Firebug.SharedEnv = Env;
-
- if (Env.isDevelopmentMode)
- {
- Env.browser.window.FBDev.loadChromeApplication(chrome);
- }
- else
- {
- var doc = chrome.document;
- var script = doc.createElement("script");
- script.src = Env.Location.app + "#remote,persist";
- doc.getElementsByTagName("head")[0].appendChild(script);
- }
- }
- else
- {
- if (chrome.type == "frame" || chrome.type == "div")
- {
- // initialize the chrome application
- setTimeout(function(){
- FBL.Firebug.initialize();
- },0);
- }
- else if (chrome.type == "popup")
- {
- var oldChrome = FirebugChrome.chromeMap.frame;
-
- var newChrome = new Chrome(chrome);
-
- // TODO: xxxpedro sync detach reattach attach
- dispatch(newChrome.panelMap, "detach", [oldChrome, newChrome]);
-
- newChrome.reattach(oldChrome, newChrome);
- }
- }
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var getChromeDivTemplate = function()
-{
- return FirebugChrome.Skin.HTML;
-};
-
-var getChromeTemplate = function(isPopup)
-{
- var tpl = FirebugChrome.Skin;
- var r = [], i = -1;
-
- r[++i] = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/DTD/strict.dtd">';
- r[++i] = '<html><head><title>';
- r[++i] = Firebug.version;
-
- /*
- r[++i] = '</title><link href="';
- r[++i] = Env.Location.skinDir + 'firebug.css';
- r[++i] = '" rel="stylesheet" type="text/css" />';
- /**/
-
- r[++i] = '</title><style>html,body{margin:0;padding:0;overflow:hidden;}';
- r[++i] = tpl.CSS;
- r[++i] = '</style>';
- /**/
-
- r[++i] = '</head><body class="fbBody' + (isPopup ? ' FirebugPopup' : '') + '">';
- r[++i] = tpl.HTML;
- r[++i] = '</body></html>';
-
- return r.join("");
-};
-
-
-// ************************************************************************************************
-// Chrome Class
-
-/**@class*/
-var Chrome = function Chrome(chrome)
-{
- var type = chrome.type;
- var Base = type == "frame" || type == "div" ? ChromeFrameBase : ChromePopupBase;
-
- append(this, Base); // inherit from base class (ChromeFrameBase or ChromePopupBase)
- append(this, chrome); // inherit chrome window properties
- append(this, new Context(chrome.window)); // inherit from Context class
-
- FirebugChrome.chromeMap[type] = this;
- Firebug.chrome = this;
- Env.chrome = chrome.window;
-
- this.commandLineVisible = false;
- this.sidePanelVisible = false;
-
- this.create();
-
- return this;
-};
-
-// ************************************************************************************************
-// ChromeBase
-
-/**
- * @namespace
- * @extends FBL.Controller
- * @extends FBL.PanelBar
- **/
-var ChromeBase = {};
-append(ChromeBase, Controller);
-append(ChromeBase, PanelBar);
-append(ChromeBase,
-/**@extend ns-chrome-ChromeBase*/
-{
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // inherited properties
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // inherited from createChrome function
-
- node: null,
- type: null,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // inherited from Context.prototype
-
- document: null,
- window: null,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // value properties
-
- sidePanelVisible: false,
- commandLineVisible: false,
- largeCommandLineVisible: false,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // object properties
-
- inspectButton: null,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- create: function()
- {
- PanelBar.create.call(this);
-
- if (Firebug.Inspector)
- this.inspectButton = new Button({
- type: "toggle",
- element: $("fbChrome_btInspect"),
- owner: Firebug.Inspector,
-
- onPress: Firebug.Inspector.startInspecting,
- onUnpress: Firebug.Inspector.stopInspecting
- });
- },
-
- destroy: function()
- {
- if(Firebug.Inspector)
- this.inspectButton.destroy();
-
- PanelBar.destroy.call(this);
-
- this.shutdown();
- },
-
- testMenu: function()
- {
- var firebugMenu = new Menu(
- {
- id: "fbFirebugMenu",
-
- items:
- [
- {
- label: "Open Firebug",
- type: "shortcut",
- key: isFirefox ? "Shift+F12" : "F12",
- checked: true,
- command: "toggleChrome"
- },
- {
- label: "Open Firebug in New Window",
- type: "shortcut",
- key: isFirefox ? "Ctrl+Shift+F12" : "Ctrl+F12",
- command: "openPopup"
- },
- {
- label: "Inspect Element",
- type: "shortcut",
- key: "Ctrl+Shift+C",
- command: "toggleInspect"
- },
- {
- label: "Command Line",
- type: "shortcut",
- key: "Ctrl+Shift+L",
- command: "focusCommandLine"
- },
- "-",
- {
- label: "Options",
- type: "group",
- child: "fbFirebugOptionsMenu"
- },
- "-",
- {
- label: "Firebug Lite Website...",
- command: "visitWebsite"
- },
- {
- label: "Discussion Group...",
- command: "visitDiscussionGroup"
- },
- {
- label: "Issue Tracker...",
- command: "visitIssueTracker"
- }
- ],
-
- onHide: function()
- {
- iconButton.restore();
- },
-
- toggleChrome: function()
- {
- Firebug.chrome.toggle();
- },
-
- openPopup: function()
- {
- Firebug.chrome.toggle(true, true);
- },
-
- toggleInspect: function()
- {
- Firebug.Inspector.toggleInspect();
- },
-
- focusCommandLine: function()
- {
- Firebug.chrome.focusCommandLine();
- },
-
- visitWebsite: function()
- {
- this.visit("http://getfirebug.com/lite.html");
- },
-
- visitDiscussionGroup: function()
- {
- this.visit("http://groups.google.com/group/firebug");
- },
-
- visitIssueTracker: function()
- {
- this.visit("http://code.google.com/p/fbug/issues/list");
- },
-
- visit: function(url)
- {
- window.open(url);
- }
-
- });
-
- /**@private*/
- var firebugOptionsMenu =
- {
- id: "fbFirebugOptionsMenu",
-
- getItems: function()
- {
- var cookiesDisabled = !Firebug.saveCookies;
-
- return [
- {
- label: "Start Opened",
- type: "checkbox",
- value: "startOpened",
- checked: Firebug.startOpened,
- disabled: cookiesDisabled
- },
- {
- label: "Start in New Window",
- type: "checkbox",
- value: "startInNewWindow",
- checked: Firebug.startInNewWindow,
- disabled: cookiesDisabled
- },
- {
- label: "Show Icon When Hidden",
- type: "checkbox",
- value: "showIconWhenHidden",
- checked: Firebug.showIconWhenHidden,
- disabled: cookiesDisabled
- },
- {
- label: "Override Console Object",
- type: "checkbox",
- value: "overrideConsole",
- checked: Firebug.overrideConsole,
- disabled: cookiesDisabled
- },
- {
- label: "Ignore Firebug Elements",
- type: "checkbox",
- value: "ignoreFirebugElements",
- checked: Firebug.ignoreFirebugElements,
- disabled: cookiesDisabled
- },
- {
- label: "Disable When Firebug Active",
- type: "checkbox",
- value: "disableWhenFirebugActive",
- checked: Firebug.disableWhenFirebugActive,
- disabled: cookiesDisabled
- },
- {
- label: "Disable XHR Listener",
- type: "checkbox",
- value: "disableXHRListener",
- checked: Firebug.disableXHRListener,
- disabled: cookiesDisabled
- },
- {
- label: "Disable Resource Fetching",
- type: "checkbox",
- value: "disableResourceFetching",
- checked: Firebug.disableResourceFetching,
- disabled: cookiesDisabled
- },
- {
- label: "Enable Trace Mode",
- type: "checkbox",
- value: "enableTrace",
- checked: Firebug.enableTrace,
- disabled: cookiesDisabled
- },
- {
- label: "Enable Persistent Mode (experimental)",
- type: "checkbox",
- value: "enablePersistent",
- checked: Firebug.enablePersistent,
- disabled: cookiesDisabled
- },
- "-",
- {
- label: "Reset All Firebug Options",
- command: "restorePrefs",
- disabled: cookiesDisabled
- }
- ];
- },
-
- onCheck: function(target, value, checked)
- {
- Firebug.setPref(value, checked);
- },
-
- restorePrefs: function(target)
- {
- Firebug.erasePrefs();
-
- if (target)
- this.updateMenu(target);
- },
-
- updateMenu: function(target)
- {
- var options = getElementsByClass(target.parentNode, "fbMenuOption");
-
- var firstOption = options[0];
- var enabled = Firebug.saveCookies;
- if (enabled)
- Menu.check(firstOption);
- else
- Menu.uncheck(firstOption);
-
- if (enabled)
- Menu.check(options[0]);
- else
- Menu.uncheck(options[0]);
-
- for (var i = 1, length = options.length; i < length; i++)
- {
- var option = options[i];
-
- var value = option.getAttribute("value");
- var pref = Firebug[value];
-
- if (pref)
- Menu.check(option);
- else
- Menu.uncheck(option);
-
- if (enabled)
- Menu.enable(option);
- else
- Menu.disable(option);
- }
- }
- };
-
- Menu.register(firebugOptionsMenu);
-
- var menu = firebugMenu;
-
- var testMenuClick = function(event)
- {
- //console.log("testMenuClick");
- cancelEvent(event, true);
-
- var target = event.target || event.srcElement;
-
- if (menu.isVisible)
- menu.hide();
- else
- {
- var offsetLeft = isIE6 ? 1 : -4, // IE6 problem with fixed position
-
- chrome = Firebug.chrome,
-
- box = chrome.getElementBox(target),
-
- offset = chrome.type == "div" ?
- chrome.getElementPosition(chrome.node) :
- {top: 0, left: 0};
-
- menu.show(
- box.left + offsetLeft - offset.left,
- box.top + box.height -5 - offset.top
- );
- }
-
- return false;
- };
-
- var iconButton = new IconButton({
- type: "toggle",
- element: $("fbFirebugButton"),
-
- onClick: testMenuClick
- });
-
- iconButton.initialize();
-
- //addEvent($("fbToolbarIcon"), "click", testMenuClick);
- },
-
- initialize: function()
- {
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- if (Env.bookmarkletOutdated)
- Firebug.Console.logFormatted([
- "A new bookmarklet version is available. " +
- "Please visit http://getfirebug.com/firebuglite#Install and update it."
- ], Firebug.context, "warn");
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- if (Firebug.Console)
- Firebug.Console.flush();
-
- if (Firebug.Trace)
- FBTrace.flush(Firebug.Trace);
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.chrome.initialize", "initializing chrome application");
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // initialize inherited classes
- Controller.initialize.call(this);
- PanelBar.initialize.call(this);
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // create the interface elements cache
-
- fbTop = $("fbTop");
- fbContent = $("fbContent");
- fbContentStyle = fbContent.style;
- fbBottom = $("fbBottom");
- fbBtnInspect = $("fbBtnInspect");
-
- fbToolbar = $("fbToolbar");
-
- fbPanelBox1 = $("fbPanelBox1");
- fbPanelBox1Style = fbPanelBox1.style;
- fbPanelBox2 = $("fbPanelBox2");
- fbPanelBox2Style = fbPanelBox2.style;
- fbPanelBar2Box = $("fbPanelBar2Box");
- fbPanelBar2BoxStyle = fbPanelBar2Box.style;
-
- fbHSplitter = $("fbHSplitter");
- fbVSplitter = $("fbVSplitter");
- fbVSplitterStyle = fbVSplitter.style;
-
- fbPanel1 = $("fbPanel1");
- fbPanel1Style = fbPanel1.style;
- fbPanel2 = $("fbPanel2");
- fbPanel2Style = fbPanel2.style;
-
- fbConsole = $("fbConsole");
- fbConsoleStyle = fbConsole.style;
- fbHTML = $("fbHTML");
-
- fbCommandLine = $("fbCommandLine");
- fbLargeCommandLine = $("fbLargeCommandLine");
- fbLargeCommandButtons = $("fbLargeCommandButtons");
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // static values cache
- topHeight = fbTop.offsetHeight;
- topPartialHeight = fbToolbar.offsetHeight;
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- disableTextSelection($("fbToolbar"));
- disableTextSelection($("fbPanelBarBox"));
- disableTextSelection($("fbPanelBar1"));
- disableTextSelection($("fbPanelBar2"));
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Add the "javascript:void(0)" href attributes used to make the hover effect in IE6
- if (isIE6 && Firebug.Selector)
- {
- // TODO: xxxpedro change to getElementsByClass
- var as = $$(".fbHover");
- for (var i=0, a; a=as[i]; i++)
- {
- a.setAttribute("href", "javascript:void(0)");
- }
- }
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // initialize all panels
- /*
- var panelMap = Firebug.panelTypes;
- for (var i=0, p; p=panelMap[i]; i++)
- {
- if (!p.parentPanel)
- {
- this.addPanel(p.prototype.name);
- }
- }
- /**/
-
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
-
- if(Firebug.Inspector)
- this.inspectButton.initialize();
-
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
-
- this.addController(
- [$("fbLargeCommandLineIcon"), "click", this.showLargeCommandLine]
- );
-
- // ************************************************************************************************
-
- // Select the first registered panel
- // TODO: BUG IE7
- var self = this;
- setTimeout(function(){
- self.selectPanel(Firebug.context.persistedState.selectedPanelName);
-
- if (Firebug.context.persistedState.selectedPanelName == "Console" && Firebug.CommandLine)
- Firebug.chrome.focusCommandLine();
- },0);
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //this.draw();
-
-
-
-
-
-
-
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- var onPanelMouseDown = function onPanelMouseDown(event)
- {
- //console.log("onPanelMouseDown", event.target || event.srcElement, event);
-
- var target = event.target || event.srcElement;
-
- if (FBL.isLeftClick(event))
- {
- var editable = FBL.getAncestorByClass(target, "editable");
-
- // if an editable element has been clicked then start editing
- if (editable)
- {
- Firebug.Editor.startEditing(editable);
- FBL.cancelEvent(event);
- }
- // if any other element has been clicked then stop editing
- else
- {
- if (!hasClass(target, "textEditorInner"))
- Firebug.Editor.stopEditing();
- }
- }
- else if (FBL.isMiddleClick(event) && Firebug.getRepNode(target))
- {
- // Prevent auto-scroll when middle-clicking a rep object
- FBL.cancelEvent(event);
- }
- };
-
- Firebug.getElementPanel = function(element)
- {
- var panelNode = getAncestorByClass(element, "fbPanel");
- var id = panelNode.id.substr(2);
-
- var panel = Firebug.chrome.panelMap[id];
-
- if (!panel)
- {
- if (Firebug.chrome.selectedPanel.sidePanelBar)
- panel = Firebug.chrome.selectedPanel.sidePanelBar.panelMap[id];
- }
-
- return panel;
- };
-
-
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- // TODO: xxxpedro port to Firebug
-
- // Improved window key code event listener. Only one "keydown" event will be attached
- // to the window, and the onKeyCodeListen() function will delegate which listeners
- // should be called according to the event.keyCode fired.
- var onKeyCodeListenersMap = [];
- var onKeyCodeListen = function(event)
- {
- for (var keyCode in onKeyCodeListenersMap)
- {
- var listeners = onKeyCodeListenersMap[keyCode];
-
- for (var i = 0, listener; listener = listeners[i]; i++)
- {
- var filter = listener.filter || FBL.noKeyModifiers;
-
- if (event.keyCode == keyCode && (!filter || filter(event)))
- {
- listener.listener();
- FBL.cancelEvent(event, true);
- return false;
- }
- }
- }
- };
-
- addEvent(Firebug.chrome.document, "keydown", onKeyCodeListen);
-
- /**
- * @name keyCodeListen
- * @memberOf FBL.FirebugChrome
- */
- Firebug.chrome.keyCodeListen = function(key, filter, listener, capture)
- {
- var keyCode = KeyEvent["DOM_VK_"+key];
-
- if (!onKeyCodeListenersMap[keyCode])
- onKeyCodeListenersMap[keyCode] = [];
-
- onKeyCodeListenersMap[keyCode].push({
- filter: filter,
- listener: listener
- });
-
- return keyCode;
- };
-
- /**
- * @name keyIgnore
- * @memberOf FBL.FirebugChrome
- */
- Firebug.chrome.keyIgnore = function(keyCode)
- {
- onKeyCodeListenersMap[keyCode] = null;
- delete onKeyCodeListenersMap[keyCode];
- };
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- /**/
- // move to shutdown
- //removeEvent(Firebug.chrome.document, "keydown", listener[0]);
-
-
- /*
- Firebug.chrome.keyCodeListen = function(key, filter, listener, capture)
- {
- if (!filter)
- filter = FBL.noKeyModifiers;
-
- var keyCode = KeyEvent["DOM_VK_"+key];
-
- var fn = function fn(event)
- {
- if (event.keyCode == keyCode && (!filter || filter(event)))
- {
- listener();
- FBL.cancelEvent(event, true);
- return false;
- }
- }
-
- addEvent(Firebug.chrome.document, "keydown", fn);
-
- return [fn, capture];
- };
-
- Firebug.chrome.keyIgnore = function(listener)
- {
- removeEvent(Firebug.chrome.document, "keydown", listener[0]);
- };
- /**/
-
-
- this.addController(
- [fbPanel1, "mousedown", onPanelMouseDown],
- [fbPanel2, "mousedown", onPanelMouseDown]
- );
-/**/
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-
- // menus can be used without domplate
- if (FBL.domplate)
- this.testMenu();
- /**/
-
- //test XHR
- /*
- setTimeout(function(){
-
- FBL.Ajax.request({url: "../content/firebug/boot.js"});
- FBL.Ajax.request({url: "../content/firebug/boot.js.invalid"});
-
- },1000);
- /**/
- },
-
- shutdown: function()
- {
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
-
- if(Firebug.Inspector)
- this.inspectButton.shutdown();
-
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- // remove disableTextSelection event handlers
- restoreTextSelection($("fbToolbar"));
- restoreTextSelection($("fbPanelBarBox"));
- restoreTextSelection($("fbPanelBar1"));
- restoreTextSelection($("fbPanelBar2"));
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // shutdown inherited classes
- Controller.shutdown.call(this);
- PanelBar.shutdown.call(this);
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Remove the interface elements cache (this must happen after calling
- // the shutdown method of all dependent components to avoid errors)
-
- fbTop = null;
- fbContent = null;
- fbContentStyle = null;
- fbBottom = null;
- fbBtnInspect = null;
-
- fbToolbar = null;
-
- fbPanelBox1 = null;
- fbPanelBox1Style = null;
- fbPanelBox2 = null;
- fbPanelBox2Style = null;
- fbPanelBar2Box = null;
- fbPanelBar2BoxStyle = null;
-
- fbHSplitter = null;
- fbVSplitter = null;
- fbVSplitterStyle = null;
-
- fbPanel1 = null;
- fbPanel1Style = null;
- fbPanel2 = null;
-
- fbConsole = null;
- fbConsoleStyle = null;
- fbHTML = null;
-
- fbCommandLine = null;
- fbLargeCommandLine = null;
- fbLargeCommandButtons = null;
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // static values cache
-
- topHeight = null;
- topPartialHeight = null;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- toggle: function(forceOpen, popup)
- {
- if(popup)
- {
- this.detach();
- }
- else
- {
- if (isOpera && Firebug.chrome.type == "popup" && Firebug.chrome.node.closed)
- {
- var frame = FirebugChrome.chromeMap.frame;
- frame.reattach();
-
- FirebugChrome.chromeMap.popup = null;
-
- frame.open();
-
- return;
- }
-
- // If the context is a popup, ignores the toggle process
- if (Firebug.chrome.type == "popup") return;
-
- var shouldOpen = forceOpen || !Firebug.context.persistedState.isOpen;
-
- if(shouldOpen)
- this.open();
- else
- this.close();
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- detach: function()
- {
- if(!FirebugChrome.chromeMap.popup)
- {
- this.close();
- createChromeWindow({type: "popup"});
- }
- },
-
- reattach: function(oldChrome, newChrome)
- {
- Firebug.browser.window.Firebug = Firebug;
-
- // chrome synchronization
- var newPanelMap = newChrome.panelMap;
- var oldPanelMap = oldChrome.panelMap;
-
- var panel;
- for(var name in newPanelMap)
- {
- // TODO: xxxpedro innerHTML
- panel = newPanelMap[name];
- if (panel.options.innerHTMLSync)
- panel.panelNode.innerHTML = oldPanelMap[name].panelNode.innerHTML;
- }
-
- Firebug.chrome = newChrome;
-
- // TODO: xxxpedro sync detach reattach attach
- //dispatch(Firebug.chrome.panelMap, "detach", [oldChrome, newChrome]);
-
- if (newChrome.type == "popup")
- {
- newChrome.initialize();
- //dispatch(Firebug.modules, "initialize", []);
- }
- else
- {
- // TODO: xxxpedro only needed in persistent
- // should use FirebugChrome.clone, but popup FBChrome
- // isn't acessible
- Firebug.context.persistedState.selectedPanelName = oldChrome.selectedPanel.name;
- }
-
- dispatch(newPanelMap, "reattach", [oldChrome, newChrome]);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- draw: function()
- {
- var size = this.getSize();
-
- // Height related values
- var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0,
-
- y = Math.max(size.height /* chrome height */, topHeight),
-
- heightValue = Math.max(y - topHeight - commandLineHeight /* fixed height */, 0),
-
- height = heightValue + "px",
-
- // Width related values
- sideWidthValue = Firebug.chrome.sidePanelVisible ? Firebug.context.persistedState.sidePanelWidth : 0,
-
- width = Math.max(size.width /* chrome width */ - sideWidthValue, 0) + "px";
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Height related rendering
- fbPanelBox1Style.height = height;
- fbPanel1Style.height = height;
-
- if (isIE || isOpera)
- {
- // Fix IE and Opera problems with auto resizing the verticall splitter
- fbVSplitterStyle.height = Math.max(y - topPartialHeight - commandLineHeight, 0) + "px";
- }
- //xxxpedro FF2 only?
- /*
- else if (isFirefox)
- {
- // Fix Firefox problem with table rows with 100% height (fit height)
- fbContentStyle.maxHeight = Math.max(y - fixedHeight, 0)+ "px";
- }/**/
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Width related rendering
- fbPanelBox1Style.width = width;
- fbPanel1Style.width = width;
-
- // SidePanel rendering
- if (Firebug.chrome.sidePanelVisible)
- {
- sideWidthValue = Math.max(sideWidthValue - 6, 0);
-
- var sideWidth = sideWidthValue + "px";
-
- fbPanelBox2Style.width = sideWidth;
-
- fbVSplitterStyle.right = sideWidth;
-
- if (Firebug.chrome.largeCommandLineVisible)
- {
- fbLargeCommandLine = $("fbLargeCommandLine");
-
- fbLargeCommandLine.style.height = heightValue - 4 + "px";
- fbLargeCommandLine.style.width = sideWidthValue - 2 + "px";
-
- fbLargeCommandButtons = $("fbLargeCommandButtons");
- fbLargeCommandButtons.style.width = sideWidth;
- }
- else
- {
- fbPanel2Style.height = height;
- fbPanel2Style.width = sideWidth;
-
- fbPanelBar2BoxStyle.width = sideWidth;
- }
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- getSize: function()
- {
- return this.type == "div" ?
- {
- height: this.node.offsetHeight,
- width: this.node.offsetWidth
- }
- :
- this.getWindowSize();
- },
-
- resize: function()
- {
- var self = this;
-
- // avoid partial resize when maximizing window
- setTimeout(function(){
- self.draw();
-
- if (noFixedPosition && (self.type == "frame" || self.type == "div"))
- self.fixIEPosition();
- }, 0);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- layout: function(panel)
- {
- if (FBTrace.DBG_CHROME) FBTrace.sysout("Chrome.layout", "");
-
- var options = panel.options;
-
- changeCommandLineVisibility(options.hasCommandLine);
- changeSidePanelVisibility(panel.hasSidePanel);
-
- Firebug.chrome.draw();
- },
-
- showLargeCommandLine: function(hideToggleIcon)
- {
- var chrome = Firebug.chrome;
-
- if (!chrome.largeCommandLineVisible)
- {
- chrome.largeCommandLineVisible = true;
-
- if (chrome.selectedPanel.options.hasCommandLine)
- {
- if (Firebug.CommandLine)
- Firebug.CommandLine.blur();
-
- changeCommandLineVisibility(false);
- }
-
- changeSidePanelVisibility(true);
-
- fbLargeCommandLine.style.display = "block";
- fbLargeCommandButtons.style.display = "block";
-
- fbPanel2Style.display = "none";
- fbPanelBar2BoxStyle.display = "none";
-
- chrome.draw();
-
- fbLargeCommandLine.focus();
-
- if (Firebug.CommandLine)
- Firebug.CommandLine.setMultiLine(true);
- }
- },
-
- hideLargeCommandLine: function()
- {
- if (Firebug.chrome.largeCommandLineVisible)
- {
- Firebug.chrome.largeCommandLineVisible = false;
-
- if (Firebug.CommandLine)
- Firebug.CommandLine.setMultiLine(false);
-
- fbLargeCommandLine.blur();
-
- fbPanel2Style.display = "block";
- fbPanelBar2BoxStyle.display = "block";
-
- fbLargeCommandLine.style.display = "none";
- fbLargeCommandButtons.style.display = "none";
-
- changeSidePanelVisibility(false);
-
- if (Firebug.chrome.selectedPanel.options.hasCommandLine)
- changeCommandLineVisibility(true);
-
- Firebug.chrome.draw();
-
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- focusCommandLine: function()
- {
- var selectedPanelName = this.selectedPanel.name, panelToSelect;
-
- if (focusCommandLineState == 0 || selectedPanelName != "Console")
- {
- focusCommandLineState = 0;
- lastFocusedPanelName = selectedPanelName;
-
- panelToSelect = "Console";
- }
- if (focusCommandLineState == 1)
- {
- panelToSelect = lastFocusedPanelName;
- }
-
- this.selectPanel(panelToSelect);
-
- try
- {
- if (Firebug.CommandLine)
- {
- if (panelToSelect == "Console")
- Firebug.CommandLine.focus();
- else
- Firebug.CommandLine.blur();
- }
- }
- catch(e)
- {
- //TODO: xxxpedro trace error
- }
-
- focusCommandLineState = ++focusCommandLineState % 2;
- }
-
-});
-
-// ************************************************************************************************
-// ChromeFrameBase
-
-/**
- * @namespace
- * @extends ns-chrome-ChromeBase
- */
-var ChromeFrameBase = extend(ChromeBase,
-/**@extend ns-chrome-ChromeFrameBase*/
-{
- create: function()
- {
- ChromeBase.create.call(this);
-
- // restore display for the anti-flicker trick
- if (isFirefox)
- this.node.style.display = "block";
-
- if (Env.Options.startInNewWindow)
- {
- this.close();
- this.toggle(true, true);
- return;
- }
-
- if (Env.Options.startOpened)
- this.open();
- else
- this.close();
- },
-
- destroy: function()
- {
- var size = Firebug.chrome.getWindowSize();
-
- Firebug.context.persistedState.height = size.height;
-
- if (Firebug.saveCookies)
- Firebug.savePrefs();
-
- removeGlobalEvent("keydown", onGlobalKeyDown);
-
- ChromeBase.destroy.call(this);
-
- this.document = null;
- delete this.document;
-
- this.window = null;
- delete this.window;
-
- this.node.parentNode.removeChild(this.node);
- this.node = null;
- delete this.node;
- },
-
- initialize: function()
- {
- //FBTrace.sysout("Frame", "initialize();")
- ChromeBase.initialize.call(this);
-
- this.addController(
- [Firebug.browser.window, "resize", this.resize],
- [$("fbWindow_btClose"), "click", this.close],
- [$("fbWindow_btDetach"), "click", this.detach],
- [$("fbWindow_btDeactivate"), "click", this.deactivate]
- );
-
- if (!Env.Options.enablePersistent)
- this.addController([Firebug.browser.window, "unload", Firebug.shutdown]);
-
- if (noFixedPosition)
- {
- this.addController(
- [Firebug.browser.window, "scroll", this.fixIEPosition]
- );
- }
-
- fbVSplitter.onmousedown = onVSplitterMouseDown;
- fbHSplitter.onmousedown = onHSplitterMouseDown;
-
- this.isInitialized = true;
- },
-
- shutdown: function()
- {
- fbVSplitter.onmousedown = null;
- fbHSplitter.onmousedown = null;
-
- ChromeBase.shutdown.apply(this);
-
- this.isInitialized = false;
- },
-
- reattach: function()
- {
- var frame = FirebugChrome.chromeMap.frame;
-
- ChromeBase.reattach(FirebugChrome.chromeMap.popup, this);
- },
-
- open: function()
- {
- if (!Firebug.context.persistedState.isOpen)
- {
- Firebug.context.persistedState.isOpen = true;
-
- if (Env.isChromeExtension)
- localStorage.setItem("Firebug", "1,1");
-
- var node = this.node;
-
- node.style.visibility = "hidden"; // Avoid flickering
-
- if (Firebug.showIconWhenHidden)
- {
- if (ChromeMini.isInitialized)
- {
- ChromeMini.shutdown();
- }
-
- }
- else
- node.style.display = "block";
-
- var main = $("fbChrome");
-
- // IE6 throws an error when setting this property! why?
- //main.style.display = "table";
- main.style.display = "";
-
- var self = this;
- /// TODO: xxxpedro FOUC
- node.style.visibility = "visible";
- setTimeout(function(){
- ///node.style.visibility = "visible";
-
- //dispatch(Firebug.modules, "initialize", []);
- self.initialize();
-
- if (noFixedPosition)
- self.fixIEPosition();
-
- self.draw();
-
- }, 10);
- }
- },
-
- close: function()
- {
- if (Firebug.context.persistedState.isOpen)
- {
- if (this.isInitialized)
- {
- //dispatch(Firebug.modules, "shutdown", []);
- this.shutdown();
- }
-
- Firebug.context.persistedState.isOpen = false;
-
- if (Env.isChromeExtension)
- localStorage.setItem("Firebug", "1,0");
-
- var node = this.node;
-
- if (Firebug.showIconWhenHidden)
- {
- node.style.visibility = "hidden"; // Avoid flickering
-
- // TODO: xxxpedro - persist IE fixed?
- var main = $("fbChrome", FirebugChrome.chromeMap.frame.document);
- main.style.display = "none";
-
- ChromeMini.initialize();
-
- node.style.visibility = "visible";
- }
- else
- node.style.display = "none";
- }
- },
-
- deactivate: function()
- {
- // if it is running as a Chrome extension, dispatch a message to the extension signaling
- // that Firebug should be deactivated for the current tab
- if (Env.isChromeExtension)
- {
- localStorage.removeItem("Firebug");
- Firebug.GoogleChrome.dispatch("FB_deactivate");
-
- // xxxpedro problem here regarding Chrome extension. We can't deactivate the whole
- // app, otherwise it won't be able to be reactivated without reloading the page.
- // but we need to stop listening global keys, otherwise the key activation won't work.
- Firebug.chrome.close();
- }
- else
- {
- Firebug.shutdown();
- }
- },
-
- fixIEPosition: function()
- {
- // fix IE problem with offset when not in fullscreen mode
- var doc = this.document;
- var offset = isIE ? doc.body.clientTop || doc.documentElement.clientTop: 0;
-
- var size = Firebug.browser.getWindowSize();
- var scroll = Firebug.browser.getWindowScrollPosition();
- var maxHeight = size.height;
- var height = this.node.offsetHeight;
-
- var bodyStyle = doc.body.currentStyle;
-
- this.node.style.top = maxHeight - height + scroll.top + "px";
-
- if ((this.type == "frame" || this.type == "div") &&
- (bodyStyle.marginLeft || bodyStyle.marginRight))
- {
- this.node.style.width = size.width + "px";
- }
-
- if (fbVSplitterStyle)
- fbVSplitterStyle.right = Firebug.context.persistedState.sidePanelWidth + "px";
-
- this.draw();
- }
-
-});
-
-
-// ************************************************************************************************
-// ChromeMini
-
-/**
- * @namespace
- * @extends FBL.Controller
- */
-var ChromeMini = extend(Controller,
-/**@extend ns-chrome-ChromeMini*/
-{
- create: function(chrome)
- {
- append(this, chrome);
- this.type = "mini";
- },
-
- initialize: function()
- {
- Controller.initialize.apply(this);
-
- var doc = FirebugChrome.chromeMap.frame.document;
-
- var mini = $("fbMiniChrome", doc);
- mini.style.display = "block";
-
- var miniIcon = $("fbMiniIcon", doc);
- var width = miniIcon.offsetWidth + 10;
- miniIcon.title = "Open " + Firebug.version;
-
- var errors = $("fbMiniErrors", doc);
- if (errors.offsetWidth)
- width += errors.offsetWidth + 10;
-
- var node = this.node;
- node.style.height = "27px";
- node.style.width = width + "px";
- node.style.left = "";
- node.style.right = 0;
-
- if (this.node.nodeName.toLowerCase() == "iframe")
- {
- node.setAttribute("allowTransparency", "true");
- this.document.body.style.backgroundColor = "transparent";
- }
- else
- node.style.background = "transparent";
-
- if (noFixedPosition)
- this.fixIEPosition();
-
- this.addController(
- [$("fbMiniIcon", doc), "click", onMiniIconClick]
- );
-
- if (noFixedPosition)
- {
- this.addController(
- [Firebug.browser.window, "scroll", this.fixIEPosition]
- );
- }
-
- this.isInitialized = true;
- },
-
- shutdown: function()
- {
- var node = this.node;
- node.style.height = Firebug.context.persistedState.height + "px";
- node.style.width = "100%";
- node.style.left = 0;
- node.style.right = "";
-
- if (this.node.nodeName.toLowerCase() == "iframe")
- {
- node.setAttribute("allowTransparency", "false");
- this.document.body.style.backgroundColor = "#fff";
- }
- else
- node.style.background = "#fff";
-
- if (noFixedPosition)
- this.fixIEPosition();
-
- var doc = FirebugChrome.chromeMap.frame.document;
-
- var mini = $("fbMiniChrome", doc);
- mini.style.display = "none";
-
- Controller.shutdown.apply(this);
-
- this.isInitialized = false;
- },
-
- draw: function()
- {
-
- },
-
- fixIEPosition: ChromeFrameBase.fixIEPosition
-
-});
-
-
-// ************************************************************************************************
-// ChromePopupBase
-
-/**
- * @namespace
- * @extends ns-chrome-ChromeBase
- */
-var ChromePopupBase = extend(ChromeBase,
-/**@extend ns-chrome-ChromePopupBase*/
-{
-
- initialize: function()
- {
- setClass(this.document.body, "FirebugPopup");
-
- ChromeBase.initialize.call(this);
-
- this.addController(
- [Firebug.chrome.window, "resize", this.resize],
- [Firebug.chrome.window, "unload", this.destroy]
- //[Firebug.chrome.window, "beforeunload", this.destroy]
- );
-
- if (Env.Options.enablePersistent)
- {
- this.persist = bind(this.persist, this);
- addEvent(Firebug.browser.window, "unload", this.persist);
- }
- else
- this.addController(
- [Firebug.browser.window, "unload", this.close]
- );
-
- fbVSplitter.onmousedown = onVSplitterMouseDown;
- },
-
- destroy: function()
- {
- var chromeWin = Firebug.chrome.window;
- var left = chromeWin.screenX || chromeWin.screenLeft;
- var top = chromeWin.screenY || chromeWin.screenTop;
- var size = Firebug.chrome.getWindowSize();
-
- Firebug.context.persistedState.popupTop = top;
- Firebug.context.persistedState.popupLeft = left;
- Firebug.context.persistedState.popupWidth = size.width;
- Firebug.context.persistedState.popupHeight = size.height;
-
- if (Firebug.saveCookies)
- Firebug.savePrefs();
-
- // TODO: xxxpedro sync detach reattach attach
- var frame = FirebugChrome.chromeMap.frame;
-
- if(frame)
- {
- dispatch(frame.panelMap, "detach", [this, frame]);
-
- frame.reattach(this, frame);
- }
-
- if (Env.Options.enablePersistent)
- {
- removeEvent(Firebug.browser.window, "unload", this.persist);
- }
-
- ChromeBase.destroy.apply(this);
-
- FirebugChrome.chromeMap.popup = null;
-
- this.node.close();
- },
-
- persist: function()
- {
- persistTimeStart = new Date().getTime();
-
- removeEvent(Firebug.browser.window, "unload", this.persist);
-
- Firebug.Inspector.destroy();
- Firebug.browser.window.FirebugOldBrowser = true;
-
- var persistTimeStart = new Date().getTime();
-
- var waitMainWindow = function()
- {
- var doc, head;
-
- try
- {
- if (window.opener && !window.opener.FirebugOldBrowser && (doc = window.opener.document)/* &&
- doc.documentElement && (head = doc.documentElement.firstChild)*/)
- {
-
- try
- {
- // exposes the FBL to the global namespace when in debug mode
- if (Env.isDebugMode)
- {
- window.FBL = FBL;
- }
-
- window.Firebug = Firebug;
- window.opener.Firebug = Firebug;
-
- Env.browser = window.opener;
- Firebug.browser = Firebug.context = new Context(Env.browser);
- Firebug.loadPrefs();
-
- registerConsole();
-
- // the delay time should be calculated right after registering the
- // console, once right after the console registration, call log messages
- // will be properly handled
- var persistDelay = new Date().getTime() - persistTimeStart;
-
- var chrome = Firebug.chrome;
- addEvent(Firebug.browser.window, "unload", chrome.persist);
-
- FBL.cacheDocument();
- Firebug.Inspector.create();
-
- Firebug.Console.logFormatted(
- ["Firebug could not capture console calls during " +
- persistDelay + "ms"],
- Firebug.context,
- "info"
- );
-
- setTimeout(function(){
- var htmlPanel = chrome.getPanel("HTML");
- htmlPanel.createUI();
- },50);
-
- }
- catch(pE)
- {
- alert("persist error: " + (pE.message || pE));
- }
-
- }
- else
- {
- window.setTimeout(waitMainWindow, 0);
- }
-
- } catch (E) {
- window.close();
- }
- };
-
- waitMainWindow();
- },
-
- close: function()
- {
- this.destroy();
- }
-
-});
-
-
-//************************************************************************************************
-// UI helpers
-
-var changeCommandLineVisibility = function changeCommandLineVisibility(visibility)
-{
- var last = Firebug.chrome.commandLineVisible;
- var visible = Firebug.chrome.commandLineVisible =
- typeof visibility == "boolean" ? visibility : !Firebug.chrome.commandLineVisible;
-
- if (visible != last)
- {
- if (visible)
- {
- fbBottom.className = "";
-
- if (Firebug.CommandLine)
- Firebug.CommandLine.activate();
- }
- else
- {
- if (Firebug.CommandLine)
- Firebug.CommandLine.deactivate();
-
- fbBottom.className = "hide";
- }
- }
-};
-
-var changeSidePanelVisibility = function changeSidePanelVisibility(visibility)
-{
- var last = Firebug.chrome.sidePanelVisible;
- Firebug.chrome.sidePanelVisible =
- typeof visibility == "boolean" ? visibility : !Firebug.chrome.sidePanelVisible;
-
- if (Firebug.chrome.sidePanelVisible != last)
- {
- fbPanelBox2.className = Firebug.chrome.sidePanelVisible ? "" : "hide";
- fbPanelBar2Box.className = Firebug.chrome.sidePanelVisible ? "" : "hide";
- }
-};
-
-
-// ************************************************************************************************
-// F12 Handler
-
-var onGlobalKeyDown = function onGlobalKeyDown(event)
-{
- var keyCode = event.keyCode;
- var shiftKey = event.shiftKey;
- var ctrlKey = event.ctrlKey;
-
- if (keyCode == 123 /* F12 */ && (!isFirefox && !shiftKey || shiftKey && isFirefox))
- {
- Firebug.chrome.toggle(false, ctrlKey);
- cancelEvent(event, true);
-
- // TODO: xxxpedro replace with a better solution. we're doing this
- // to allow reactivating with the F12 key after being deactivated
- if (Env.isChromeExtension)
- {
- Firebug.GoogleChrome.dispatch("FB_enableIcon");
- }
- }
- else if (keyCode == 67 /* C */ && ctrlKey && shiftKey)
- {
- Firebug.Inspector.toggleInspect();
- cancelEvent(event, true);
- }
- else if (keyCode == 76 /* L */ && ctrlKey && shiftKey)
- {
- Firebug.chrome.focusCommandLine();
- cancelEvent(event, true);
- }
-};
-
-var onMiniIconClick = function onMiniIconClick(event)
-{
- Firebug.chrome.toggle(false, event.ctrlKey);
- cancelEvent(event, true);
-};
-
-
-// ************************************************************************************************
-// Horizontal Splitter Handling
-
-var onHSplitterMouseDown = function onHSplitterMouseDown(event)
-{
- addGlobalEvent("mousemove", onHSplitterMouseMove);
- addGlobalEvent("mouseup", onHSplitterMouseUp);
-
- if (isIE)
- addEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp);
-
- fbHSplitter.className = "fbOnMovingHSplitter";
-
- return false;
-};
-
-var onHSplitterMouseMove = function onHSplitterMouseMove(event)
-{
- cancelEvent(event, true);
-
- var clientY = event.clientY;
- var win = isIE
- ? event.srcElement.ownerDocument.parentWindow
- : event.target.defaultView || event.target.ownerDocument && event.target.ownerDocument.defaultView;
-
- if (!win)
- return;
-
- if (win != win.parent)
- {
- var frameElement = win.frameElement;
- if (frameElement)
- {
- var framePos = Firebug.browser.getElementPosition(frameElement).top;
- clientY += framePos;
-
- if (frameElement.style.position != "fixed")
- clientY -= Firebug.browser.getWindowScrollPosition().top;
- }
- }
-
- if (isOpera && isQuiksMode && win.frameElement.id == "FirebugUI")
- {
- clientY = Firebug.browser.getWindowSize().height - win.frameElement.offsetHeight + clientY;
- }
-
- /*
- console.log(
- typeof win.FBL != "undefined" ? "no-Chrome" : "Chrome",
- //win.frameElement.id,
- event.target,
- clientY
- );/**/
-
- onHSplitterMouseMoveBuffer = clientY; // buffer
-
- if (new Date().getTime() - lastHSplitterMouseMove > chromeRedrawSkipRate) // frame skipping
- {
- lastHSplitterMouseMove = new Date().getTime();
- handleHSplitterMouseMove();
- }
- else
- if (!onHSplitterMouseMoveTimer)
- onHSplitterMouseMoveTimer = setTimeout(handleHSplitterMouseMove, chromeRedrawSkipRate);
-
- // improving the resizing performance by canceling the mouse event.
- // canceling events will prevent the page to receive such events, which would imply
- // in more processing being expended.
- cancelEvent(event, true);
- return false;
-};
-
-var handleHSplitterMouseMove = function()
-{
- if (onHSplitterMouseMoveTimer)
- {
- clearTimeout(onHSplitterMouseMoveTimer);
- onHSplitterMouseMoveTimer = null;
- }
-
- var clientY = onHSplitterMouseMoveBuffer;
-
- var windowSize = Firebug.browser.getWindowSize();
- var scrollSize = Firebug.browser.getWindowScrollSize();
-
- // compute chrome fixed size (top bar and command line)
- var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0;
- var fixedHeight = topHeight + commandLineHeight;
- var chromeNode = Firebug.chrome.node;
-
- var scrollbarSize = !isIE && (scrollSize.width > windowSize.width) ? 17 : 0;
-
- //var height = !isOpera ? chromeNode.offsetTop + chromeNode.clientHeight : windowSize.height;
- var height = windowSize.height;
-
- // compute the min and max size of the chrome
- var chromeHeight = Math.max(height - clientY + 5 - scrollbarSize, fixedHeight);
- chromeHeight = Math.min(chromeHeight, windowSize.height - scrollbarSize);
-
- Firebug.context.persistedState.height = chromeHeight;
- chromeNode.style.height = chromeHeight + "px";
-
- if (noFixedPosition)
- Firebug.chrome.fixIEPosition();
-
- Firebug.chrome.draw();
-};
-
-var onHSplitterMouseUp = function onHSplitterMouseUp(event)
-{
- removeGlobalEvent("mousemove", onHSplitterMouseMove);
- removeGlobalEvent("mouseup", onHSplitterMouseUp);
-
- if (isIE)
- removeEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp);
-
- fbHSplitter.className = "";
-
- Firebug.chrome.draw();
-
- // avoid text selection in IE when returning to the document
- // after the mouse leaves the document during the resizing
- return false;
-};
-
-
-// ************************************************************************************************
-// Vertical Splitter Handling
-
-var onVSplitterMouseDown = function onVSplitterMouseDown(event)
-{
- addGlobalEvent("mousemove", onVSplitterMouseMove);
- addGlobalEvent("mouseup", onVSplitterMouseUp);
-
- return false;
-};
-
-var onVSplitterMouseMove = function onVSplitterMouseMove(event)
-{
- if (new Date().getTime() - lastVSplitterMouseMove > chromeRedrawSkipRate) // frame skipping
- {
- var target = event.target || event.srcElement;
- if (target && target.ownerDocument) // avoid error when cursor reaches out of the chrome
- {
- var clientX = event.clientX;
- var win = document.all
- ? event.srcElement.ownerDocument.parentWindow
- : event.target.ownerDocument.defaultView;
-
- if (win != win.parent)
- clientX += win.frameElement ? win.frameElement.offsetLeft : 0;
-
- var size = Firebug.chrome.getSize();
- var x = Math.max(size.width - clientX + 3, 6);
-
- Firebug.context.persistedState.sidePanelWidth = x;
- Firebug.chrome.draw();
- }
-
- lastVSplitterMouseMove = new Date().getTime();
- }
-
- cancelEvent(event, true);
- return false;
-};
-
-var onVSplitterMouseUp = function onVSplitterMouseUp(event)
-{
- removeGlobalEvent("mousemove", onVSplitterMouseMove);
- removeGlobalEvent("mouseup", onVSplitterMouseUp);
-
- Firebug.chrome.draw();
-};
-
-
-// ************************************************************************************************
-}});
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-Firebug.Lite =
-{
-};
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-Firebug.Lite.Cache =
-{
- ID: "firebug-" + new Date().getTime()
-};
-
-// ************************************************************************************************
-
-/**
- * TODO: if a cached element is cloned, the expando property will be cloned too in IE
- * which will result in a bug. Firebug Lite will think the new cloned node is the old
- * one.
- *
- * TODO: Investigate a possibility of cache validation, to be customized by each
- * kind of cache. For ElementCache it should validate if the element still is
- * inserted at the DOM.
- */
-var cacheUID = 0;
-var createCache = function()
-{
- var map = {};
- var data = {};
-
- var CID = Firebug.Lite.Cache.ID;
-
- // better detection
- var supportsDeleteExpando = !document.all;
-
- var cacheFunction = function(element)
- {
- return cacheAPI.set(element);
- };
-
- var cacheAPI =
- {
- get: function(key)
- {
- return map.hasOwnProperty(key) ?
- map[key] :
- null;
- },
-
- set: function(element)
- {
- var id = getValidatedKey(element);
-
- if (!id)
- {
- id = ++cacheUID;
- element[CID] = id;
- }
-
- if (!map.hasOwnProperty(id))
- {
- map[id] = element;
- data[id] = {};
- }
-
- return id;
- },
-
- unset: function(element)
- {
- var id = getValidatedKey(element);
-
- if (!id) return;
-
- if (supportsDeleteExpando)
- {
- delete element[CID];
- }
- else if (element.removeAttribute)
- {
- element.removeAttribute(CID);
- }
-
- delete map[id];
- delete data[id];
-
- },
-
- key: function(element)
- {
- return getValidatedKey(element);
- },
-
- has: function(element)
- {
- var id = getValidatedKey(element);
- return id && map.hasOwnProperty(id);
- },
-
- each: function(callback)
- {
- for (var key in map)
- {
- if (map.hasOwnProperty(key))
- {
- callback(key, map[key]);
- }
- }
- },
-
- data: function(element, name, value)
- {
- // set data
- if (value)
- {
- if (!name) return null;
-
- var id = cacheAPI.set(element);
-
- return data[id][name] = value;
- }
- // get data
- else
- {
- var id = cacheAPI.key(element);
-
- return data.hasOwnProperty(id) && data[id].hasOwnProperty(name) ?
- data[id][name] :
- null;
- }
- },
-
- clear: function()
- {
- for (var id in map)
- {
- var element = map[id];
- cacheAPI.unset(element);
- }
- }
- };
-
- var getValidatedKey = function(element)
- {
- var id = element[CID];
-
- // If a cached element is cloned in IE, the expando property CID will be also
- // cloned (differently than other browsers) resulting in a bug: Firebug Lite
- // will think the new cloned node is the old one. To prevent this problem we're
- // checking if the cached element matches the given element.
- if (
- !supportsDeleteExpando && // the problem happens when supportsDeleteExpando is false
- id && // the element has the expando property
- map.hasOwnProperty(id) && // there is a cached element with the same id
- map[id] != element // but it is a different element than the current one
- )
- {
- // remove the problematic property
- element.removeAttribute(CID);
-
- id = null;
- }
-
- return id;
- };
-
- FBL.append(cacheFunction, cacheAPI);
-
- return cacheFunction;
-};
-
-// ************************************************************************************************
-
-// TODO: xxxpedro : check if we need really this on FBL scope
-Firebug.Lite.Cache.StyleSheet = createCache();
-Firebug.Lite.Cache.Element = createCache();
-
-// TODO: xxxpedro
-Firebug.Lite.Cache.Event = createCache();
-
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-// ************************************************************************************************
-var sourceMap = {};
-
-// ************************************************************************************************
-Firebug.Lite.Proxy =
-{
- // jsonp callbacks
- _callbacks: {},
-
- /**
- * Load a resource, either locally (directly) or externally (via proxy) using
- * synchronous XHR calls. Loading external resources requires the proxy plugin to
- * be installed and configured (see /plugin/proxy/proxy.php).
- */
- load: function(url)
- {
- var resourceDomain = getDomain(url);
- var isLocalResource =
- // empty domain means local URL
- !resourceDomain ||
- // same domain means local too
- resourceDomain == Firebug.context.window.location.host; // TODO: xxxpedro context
-
- return isLocalResource ? fetchResource(url) : fetchProxyResource(url);
- },
-
- /**
- * Load a resource using JSONP technique.
- */
- loadJSONP: function(url, callback)
- {
- var script = createGlobalElement("script"),
- doc = Firebug.context.document,
-
- uid = "" + new Date().getTime(),
- callbackName = "callback=Firebug.Lite.Proxy._callbacks." + uid,
-
- jsonpURL = url.indexOf("?") != -1 ?
- url + "&" + callbackName :
- url + "?" + callbackName;
-
- Firebug.Lite.Proxy._callbacks[uid] = function(data)
- {
- if (callback)
- callback(data);
-
- script.parentNode.removeChild(script);
- delete Firebug.Lite.Proxy._callbacks[uid];
- };
-
- script.src = jsonpURL;
-
- if (doc.documentElement)
- doc.documentElement.appendChild(script);
- },
-
- /**
- * Load a resource using YQL (not reliable).
- */
- YQL: function(url, callback)
- {
- var yql = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" +
- encodeURIComponent(url) + "%22&format=xml";
-
- this.loadJSONP(yql, function(data)
- {
- var source = data.results[0];
-
- // clean up YQL bogus elements
- var match = /<body>\s+<p>([\s\S]+)<\/p>\s+<\/body>$/.exec(source);
- if (match)
- source = match[1];
-
- console.log(source);
- });
- }
-};
-
-// ************************************************************************************************
-
-Firebug.Lite.Proxy.fetchResourceDisabledMessage =
- "/* Firebug Lite resource fetching is disabled.\n" +
- "To enabled it set the Firebug Lite option \"disableResourceFetching\" to \"false\".\n" +
- "More info at http://getfirebug.com/firebuglite#Options */";
-
-var fetchResource = function(url)
-{
- if (Firebug.disableResourceFetching)
- {
- var source = sourceMap[url] = Firebug.Lite.Proxy.fetchResourceDisabledMessage;
- return source;
- }
-
- if (sourceMap.hasOwnProperty(url))
- return sourceMap[url];
-
- // Getting the native XHR object so our calls won't be logged in the Console Panel
- var xhr = FBL.getNativeXHRObject();
- xhr.open("get", url, false);
- xhr.send();
-
- var source = sourceMap[url] = xhr.responseText;
- return source;
-};
-
-var fetchProxyResource = function(url)
-{
- if (sourceMap.hasOwnProperty(url))
- return sourceMap[url];
-
- var proxyURL = Env.Location.baseDir + "plugin/proxy/proxy.php?url=" + encodeURIComponent(url);
- var response = fetchResource(proxyURL);
-
- try
- {
- var data = eval("(" + response + ")");
- }
- catch(E)
- {
- return "ERROR: Firebug Lite Proxy plugin returned an invalid response.";
- }
-
- var source = data ? data.contents : "";
- return source;
-};
-
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-Firebug.Lite.Style =
-{
-};
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-Firebug.Lite.Script = function(window)
-{
- this.fileName = null;
- this.isValid = null;
- this.baseLineNumber = null;
- this.lineExtent = null;
- this.tag = null;
-
- this.functionName = null;
- this.functionSource = null;
-};
-
-Firebug.Lite.Script.prototype =
-{
- isLineExecutable: function(){},
- pcToLine: function(){},
- lineToPc: function(){},
-
- toString: function()
- {
- return "Firebug.Lite.Script";
- }
-};
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-
-Firebug.Lite.Browser = function(window)
-{
- this.contentWindow = window;
- this.contentDocument = window.document;
- this.currentURI =
- {
- spec: window.location.href
- };
-};
-
-Firebug.Lite.Browser.prototype =
-{
- toString: function()
- {
- return "Firebug.Lite.Browser";
- }
-};
-
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-/*
- http://www.JSON.org/json2.js
- 2010-03-20
-
- Public Domain.
-
- NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
-
- See http://www.JSON.org/js.html
-
-
- This code should be minified before deployment.
- See http://javascript.crockford.com/jsmin.html
-
- USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
- NOT CONTROL.
-
-
- This file creates a global JSON object containing two methods: stringify
- and parse.
-
- JSON.stringify(value, replacer, space)
- value any JavaScript value, usually an object or array.
-
- replacer an optional parameter that determines how object
- values are stringified for objects. It can be a
- function or an array of strings.
-
- space an optional parameter that specifies the indentation
- of nested structures. If it is omitted, the text will
- be packed without extra whitespace. If it is a number,
- it will specify the number of spaces to indent at each
- level. If it is a string (such as '\t' or '&nbsp;'),
- it contains the characters used to indent at each level.
-
- This method produces a JSON text from a JavaScript value.
-
- When an object value is found, if the object contains a toJSON
- method, its toJSON method will be called and the result will be
- stringified. A toJSON method does not serialize: it returns the
- value represented by the name/value pair that should be serialized,
- or undefined if nothing should be serialized. The toJSON method
- will be passed the key associated with the value, and this will be
- bound to the value
-
- For example, this would serialize Dates as ISO strings.
-
- Date.prototype.toJSON = function (key) {
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- return this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z';
- };
-
- You can provide an optional replacer method. It will be passed the
- key and value of each member, with this bound to the containing
- object. The value that is returned from your method will be
- serialized. If your method returns undefined, then the member will
- be excluded from the serialization.
-
- If the replacer parameter is an array of strings, then it will be
- used to select the members to be serialized. It filters the results
- such that only members with keys listed in the replacer array are
- stringified.
-
- Values that do not have JSON representations, such as undefined or
- functions, will not be serialized. Such values in objects will be
- dropped; in arrays they will be replaced with null. You can use
- a replacer function to replace those with JSON values.
- JSON.stringify(undefined) returns undefined.
-
- The optional space parameter produces a stringification of the
- value that is filled with line breaks and indentation to make it
- easier to read.
-
- If the space parameter is a non-empty string, then that string will
- be used for indentation. If the space parameter is a number, then
- the indentation will be that many spaces.
-
- Example:
-
- text = JSON.stringify(['e', {pluribus: 'unum'}]);
- // text is '["e",{"pluribus":"unum"}]'
-
-
- text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
- // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
-
- text = JSON.stringify([new Date()], function (key, value) {
- return this[key] instanceof Date ?
- 'Date(' + this[key] + ')' : value;
- });
- // text is '["Date(---current time---)"]'
-
-
- JSON.parse(text, reviver)
- This method parses a JSON text to produce an object or array.
- It can throw a SyntaxError exception.
-
- The optional reviver parameter is a function that can filter and
- transform the results. It receives each of the keys and values,
- and its return value is used instead of the original value.
- If it returns what it received, then the structure is not modified.
- If it returns undefined then the member is deleted.
-
- Example:
-
- // Parse the text. Values that look like ISO date strings will
- // be converted to Date objects.
-
- myData = JSON.parse(text, function (key, value) {
- var a;
- if (typeof value === 'string') {
- a =
-/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
- if (a) {
- return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
- +a[5], +a[6]));
- }
- }
- return value;
- });
-
- myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
- var d;
- if (typeof value === 'string' &&
- value.slice(0, 5) === 'Date(' &&
- value.slice(-1) === ')') {
- d = new Date(value.slice(5, -1));
- if (d) {
- return d;
- }
- }
- return value;
- });
-
-
- This is a reference implementation. You are free to copy, modify, or
- redistribute.
-*/
-
-/*jslint evil: true, strict: false */
-
-/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
- call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
- getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
- lastIndex, length, parse, prototype, push, replace, slice, stringify,
- test, toJSON, toString, valueOf
-*/
-
-
-// Create a JSON object only if one does not already exist. We create the
-// methods in a closure to avoid creating global variables.
-
-// ************************************************************************************************
-
-var JSON = window.JSON || {};
-
-// ************************************************************************************************
-
-(function () {
-
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- if (typeof Date.prototype.toJSON !== 'function') {
-
- Date.prototype.toJSON = function (key) {
-
- return isFinite(this.valueOf()) ?
- this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z' : null;
- };
-
- String.prototype.toJSON =
- Number.prototype.toJSON =
- Boolean.prototype.toJSON = function (key) {
- return this.valueOf();
- };
- }
-
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- gap,
- indent,
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- },
- rep;
-
-
- function quote(string) {
-
-// If the string contains no control characters, no quote characters, and no
-// backslash characters, then we can safely slap some quotes around it.
-// Otherwise we must also replace the offending characters with safe escape
-// sequences.
-
- escapable.lastIndex = 0;
- return escapable.test(string) ?
- '"' + string.replace(escapable, function (a) {
- var c = meta[a];
- return typeof c === 'string' ? c :
- '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- }) + '"' :
- '"' + string + '"';
- }
-
-
- function str(key, holder) {
-
-// Produce a string from holder[key].
-
- var i, // The loop counter.
- k, // The member key.
- v, // The member value.
- length,
- mind = gap,
- partial,
- value = holder[key];
-
-// If the value has a toJSON method, call it to obtain a replacement value.
-
- if (value && typeof value === 'object' &&
- typeof value.toJSON === 'function') {
- value = value.toJSON(key);
- }
-
-// If we were called with a replacer function, then call the replacer to
-// obtain a replacement value.
-
- if (typeof rep === 'function') {
- value = rep.call(holder, key, value);
- }
-
-// What happens next depends on the value's type.
-
- switch (typeof value) {
- case 'string':
- return quote(value);
-
- case 'number':
-
-// JSON numbers must be finite. Encode non-finite numbers as null.
-
- return isFinite(value) ? String(value) : 'null';
-
- case 'boolean':
- case 'null':
-
-// If the value is a boolean or null, convert it to a string. Note:
-// typeof null does not produce 'null'. The case is included here in
-// the remote chance that this gets fixed someday.
-
- return String(value);
-
-// If the type is 'object', we might be dealing with an object or an array or
-// null.
-
- case 'object':
-
-// Due to a specification blunder in ECMAScript, typeof null is 'object',
-// so watch out for that case.
-
- if (!value) {
- return 'null';
- }
-
-// Make an array to hold the partial results of stringifying this object value.
-
- gap += indent;
- partial = [];
-
-// Is the value an array?
-
- if (Object.prototype.toString.apply(value) === '[object Array]') {
-
-// The value is an array. Stringify every element. Use null as a placeholder
-// for non-JSON values.
-
- length = value.length;
- for (i = 0; i < length; i += 1) {
- partial[i] = str(i, value) || 'null';
- }
-
-// Join all of the elements together, separated with commas, and wrap them in
-// brackets.
-
- v = partial.length === 0 ? '[]' :
- gap ? '[\n' + gap +
- partial.join(',\n' + gap) + '\n' +
- mind + ']' :
- '[' + partial.join(',') + ']';
- gap = mind;
- return v;
- }
-
-// If the replacer is an array, use it to select the members to be stringified.
-
- if (rep && typeof rep === 'object') {
- length = rep.length;
- for (i = 0; i < length; i += 1) {
- k = rep[i];
- if (typeof k === 'string') {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- } else {
-
-// Otherwise, iterate through all of the keys in the object.
-
- for (k in value) {
- if (Object.hasOwnProperty.call(value, k)) {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- }
-
-// Join all of the member texts together, separated with commas,
-// and wrap them in braces.
-
- v = partial.length === 0 ? '{}' :
- gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
- mind + '}' : '{' + partial.join(',') + '}';
- gap = mind;
- return v;
- }
- }
-
-// If the JSON object does not yet have a stringify method, give it one.
-
- if (typeof JSON.stringify !== 'function') {
- JSON.stringify = function (value, replacer, space) {
-
-// The stringify method takes a value and an optional replacer, and an optional
-// space parameter, and returns a JSON text. The replacer can be a function
-// that can replace values, or an array of strings that will select the keys.
-// A default replacer method can be provided. Use of the space parameter can
-// produce text that is more easily readable.
-
- var i;
- gap = '';
- indent = '';
-
-// If the space parameter is a number, make an indent string containing that
-// many spaces.
-
- if (typeof space === 'number') {
- for (i = 0; i < space; i += 1) {
- indent += ' ';
- }
-
-// If the space parameter is a string, it will be used as the indent string.
-
- } else if (typeof space === 'string') {
- indent = space;
- }
-
-// If there is a replacer, it must be a function or an array.
-// Otherwise, throw an error.
-
- rep = replacer;
- if (replacer && typeof replacer !== 'function' &&
- (typeof replacer !== 'object' ||
- typeof replacer.length !== 'number')) {
- throw new Error('JSON.stringify');
- }
-
-// Make a fake root object containing our value under the key of ''.
-// Return the result of stringifying the value.
-
- return str('', {'': value});
- };
- }
-
-
-// If the JSON object does not yet have a parse method, give it one.
-
- if (typeof JSON.parse !== 'function') {
- JSON.parse = function (text, reviver) {
-
-// The parse method takes a text and an optional reviver function, and returns
-// a JavaScript value if the text is a valid JSON text.
-
- var j;
-
- function walk(holder, key) {
-
-// The walk method is used to recursively walk the resulting structure so
-// that modifications can be made.
-
- var k, v, value = holder[key];
- if (value && typeof value === 'object') {
- for (k in value) {
- if (Object.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }
-
-
-// Parsing happens in four stages. In the first stage, we replace certain
-// Unicode characters with escape sequences. JavaScript handles many characters
-// incorrectly, either silently deleting them, or treating them as line endings.
-
- text = String(text);
- cx.lastIndex = 0;
- if (cx.test(text)) {
- text = text.replace(cx, function (a) {
- return '\\u' +
- ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- });
- }
-
-// In the second stage, we run the text against regular expressions that look
-// for non-JSON patterns. We are especially concerned with '()' and 'new'
-// because they can cause invocation, and '=' because it can cause mutation.
-// But just to be safe, we want to reject all unexpected forms.
-
-// We split the second stage into 4 regexp operations in order to work around
-// crippling inefficiencies in IE's and Safari's regexp engines. First we
-// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
-// replace all simple value tokens with ']' characters. Third, we delete all
-// open brackets that follow a colon or comma or that begin the text. Finally,
-// we look to see that the remaining characters are only whitespace or ']' or
-// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
-
- if (/^[\],:{}\s]*$/.
-test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
-replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
-replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
-
-// In the third stage we use the eval function to compile the text into a
-// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
-// in JavaScript: it can begin a block or an object literal. We wrap the text
-// in parens to eliminate the ambiguity.
-
- j = eval('(' + text + ')');
-
-// In the optional fourth stage, we recursively walk the new structure, passing
-// each name/value pair to a reviver function for possible transformation.
-
- return typeof reviver === 'function' ?
- walk({'': j}, '') : j;
- }
-
-// If the text is not JSON parseable, then a SyntaxError is thrown.
-
- throw new SyntaxError('JSON.parse');
- };
- }
-
-// ************************************************************************************************
-// registration
-
-FBL.JSON = JSON;
-
-// ************************************************************************************************
-}());
-
-/* See license.txt for terms of usage */
-
-(function(){
-// ************************************************************************************************
-
-/* Copyright (c) 2010-2011 Marcus Westin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-var store = (function(){
- var api = {},
- win = window,
- doc = win.document,
- localStorageName = 'localStorage',
- globalStorageName = 'globalStorage',
- namespace = '__firebug__storejs__',
- storage
-
- api.disabled = false
- api.set = function(key, value) {}
- api.get = function(key) {}
- api.remove = function(key) {}
- api.clear = function() {}
- api.transact = function(key, transactionFn) {
- var val = api.get(key)
- if (typeof val == 'undefined') { val = {} }
- transactionFn(val)
- api.set(key, val)
- }
-
- api.serialize = function(value) {
- return JSON.stringify(value)
- }
- api.deserialize = function(value) {
- if (typeof value != 'string') { return undefined }
- return JSON.parse(value)
- }
-
- // Functions to encapsulate questionable FireFox 3.6.13 behavior
- // when about.config::dom.storage.enabled === false
- // See https://github.com/marcuswestin/store.js/issues#issue/13
- function isLocalStorageNameSupported() {
- try { return (localStorageName in win && win[localStorageName]) }
- catch(err) { return false }
- }
-
- function isGlobalStorageNameSupported() {
- try { return (globalStorageName in win && win[globalStorageName] && win[globalStorageName][win.location.hostname]) }
- catch(err) { return false }
- }
-
- if (isLocalStorageNameSupported()) {
- storage = win[localStorageName]
- api.set = function(key, val) { storage.setItem(key, api.serialize(val)) }
- api.get = function(key) { return api.deserialize(storage.getItem(key)) }
- api.remove = function(key) { storage.removeItem(key) }
- api.clear = function() { storage.clear() }
-
- } else if (isGlobalStorageNameSupported()) {
- storage = win[globalStorageName][win.location.hostname]
- api.set = function(key, val) { storage[key] = api.serialize(val) }
- api.get = function(key) { return api.deserialize(storage[key] && storage[key].value) }
- api.remove = function(key) { delete storage[key] }
- api.clear = function() { for (var key in storage ) { delete storage[key] } }
-
- } else if (doc.documentElement.addBehavior) {
- var storage = doc.createElement('div')
- function withIEStorage(storeFunction) {
- return function() {
- var args = Array.prototype.slice.call(arguments, 0)
- args.unshift(storage)
- // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
- // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
- // TODO: xxxpedro doc.body is not always available so we must use doc.documentElement.
- // We need to make sure this change won't affect the behavior of this library.
- doc.documentElement.appendChild(storage)
- storage.addBehavior('#default#userData')
- storage.load(localStorageName)
- var result = storeFunction.apply(api, args)
- doc.documentElement.removeChild(storage)
- return result
- }
- }
- api.set = withIEStorage(function(storage, key, val) {
- storage.setAttribute(key, api.serialize(val))
- storage.save(localStorageName)
- })
- api.get = withIEStorage(function(storage, key) {
- return api.deserialize(storage.getAttribute(key))
- })
- api.remove = withIEStorage(function(storage, key) {
- storage.removeAttribute(key)
- storage.save(localStorageName)
- })
- api.clear = withIEStorage(function(storage) {
- var attributes = storage.XMLDocument.documentElement.attributes
- storage.load(localStorageName)
- for (var i=0, attr; attr = attributes[i]; i++) {
- storage.removeAttribute(attr.name)
- }
- storage.save(localStorageName)
- })
- }
-
- try {
- api.set(namespace, namespace)
- if (api.get(namespace) != namespace) { api.disabled = true }
- api.remove(namespace)
- } catch(e) {
- api.disabled = true
- }
-
- return api
-})();
-
-if (typeof module != 'undefined') { module.exports = store }
-
-
-// ************************************************************************************************
-// registration
-
-FBL.Store = store;
-
-// ************************************************************************************************
-})();
-
-/* See license.txt for terms of usage */
-
-FBL.ns( /**@scope s_selector*/ function() { with (FBL) {
-// ************************************************************************************************
-
-/*
- * Sizzle CSS Selector Engine - v1.0
- * Copyright 2009, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
- * More information: http://sizzlejs.com/
- */
-
-var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
- done = 0,
- toString = Object.prototype.toString,
- hasDuplicate = false,
- baseHasDuplicate = true;
-
-// Here we check if the JavaScript engine is using some sort of
-// optimization where it does not always call our comparision
-// function. If that is the case, discard the hasDuplicate value.
-// Thus far that includes Google Chrome.
-[0, 0].sort(function(){
- baseHasDuplicate = false;
- return 0;
-});
-
-/**
- * @name Firebug.Selector
- * @namespace
- */
-
-/**
- * @exports Sizzle as Firebug.Selector
- */
-var Sizzle = function(selector, context, results, seed) {
- results = results || [];
- var origContext = context = context || document;
-
- if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
- return [];
- }
-
- if ( !selector || typeof selector !== "string" ) {
- return results;
- }
-
- var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
- soFar = selector;
-
- // Reset the position of the chunker regexp (start from head)
- while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
- soFar = m[3];
-
- parts.push( m[1] );
-
- if ( m[2] ) {
- extra = m[3];
- break;
- }
- }
-
- if ( parts.length > 1 && origPOS.exec( selector ) ) {
- if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
- set = posProcess( parts[0] + parts[1], context );
- } else {
- set = Expr.relative[ parts[0] ] ?
- [ context ] :
- Sizzle( parts.shift(), context );
-
- while ( parts.length ) {
- selector = parts.shift();
-
- if ( Expr.relative[ selector ] )
- selector += parts.shift();
-
- set = posProcess( selector, set );
- }
- }
- } else {
- // Take a shortcut and set the context if the root selector is an ID
- // (but not if it'll be faster if the inner selector is an ID)
- if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
- Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
- var ret = Sizzle.find( parts.shift(), context, contextXML );
- context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
- }
-
- if ( context ) {
- var ret = seed ?
- { expr: parts.pop(), set: makeArray(seed) } :
- Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
- set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
-
- if ( parts.length > 0 ) {
- checkSet = makeArray(set);
- } else {
- prune = false;
- }
-
- while ( parts.length ) {
- var cur = parts.pop(), pop = cur;
-
- if ( !Expr.relative[ cur ] ) {
- cur = "";
- } else {
- pop = parts.pop();
- }
-
- if ( pop == null ) {
- pop = context;
- }
-
- Expr.relative[ cur ]( checkSet, pop, contextXML );
- }
- } else {
- checkSet = parts = [];
- }
- }
-
- if ( !checkSet ) {
- checkSet = set;
- }
-
- if ( !checkSet ) {
- throw "Syntax error, unrecognized expression: " + (cur || selector);
- }
-
- if ( toString.call(checkSet) === "[object Array]" ) {
- if ( !prune ) {
- results.push.apply( results, checkSet );
- } else if ( context && context.nodeType === 1 ) {
- for ( var i = 0; checkSet[i] != null; i++ ) {
- if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
- results.push( set[i] );
- }
- }
- } else {
- for ( var i = 0; checkSet[i] != null; i++ ) {
- if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
- results.push( set[i] );
- }
- }
- }
- } else {
- makeArray( checkSet, results );
- }
-
- if ( extra ) {
- Sizzle( extra, origContext, results, seed );
- Sizzle.uniqueSort( results );
- }
-
- return results;
-};
-
-Sizzle.uniqueSort = function(results){
- if ( sortOrder ) {
- hasDuplicate = baseHasDuplicate;
- results.sort(sortOrder);
-
- if ( hasDuplicate ) {
- for ( var i = 1; i < results.length; i++ ) {
- if ( results[i] === results[i-1] ) {
- results.splice(i--, 1);
- }
- }
- }
- }
-
- return results;
-};
-
-Sizzle.matches = function(expr, set){
- return Sizzle(expr, null, null, set);
-};
-
-Sizzle.find = function(expr, context, isXML){
- var set, match;
-
- if ( !expr ) {
- return [];
- }
-
- for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
- var type = Expr.order[i], match;
-
- if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
- var left = match[1];
- match.splice(1,1);
-
- if ( left.substr( left.length - 1 ) !== "\\" ) {
- match[1] = (match[1] || "").replace(/\\/g, "");
- set = Expr.find[ type ]( match, context, isXML );
- if ( set != null ) {
- expr = expr.replace( Expr.match[ type ], "" );
- break;
- }
- }
- }
- }
-
- if ( !set ) {
- set = context.getElementsByTagName("*");
- }
-
- return {set: set, expr: expr};
-};
-
-Sizzle.filter = function(expr, set, inplace, not){
- var old = expr, result = [], curLoop = set, match, anyFound,
- isXMLFilter = set && set[0] && isXML(set[0]);
-
- while ( expr && set.length ) {
- for ( var type in Expr.filter ) {
- if ( (match = Expr.match[ type ].exec( expr )) != null ) {
- var filter = Expr.filter[ type ], found, item;
- anyFound = false;
-
- if ( curLoop == result ) {
- result = [];
- }
-
- if ( Expr.preFilter[ type ] ) {
- match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
-
- if ( !match ) {
- anyFound = found = true;
- } else if ( match === true ) {
- continue;
- }
- }
-
- if ( match ) {
- for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
- if ( item ) {
- found = filter( item, match, i, curLoop );
- var pass = not ^ !!found;
-
- if ( inplace && found != null ) {
- if ( pass ) {
- anyFound = true;
- } else {
- curLoop[i] = false;
- }
- } else if ( pass ) {
- result.push( item );
- anyFound = true;
- }
- }
- }
- }
-
- if ( found !== undefined ) {
- if ( !inplace ) {
- curLoop = result;
- }
-
- expr = expr.replace( Expr.match[ type ], "" );
-
- if ( !anyFound ) {
- return [];
- }
-
- break;
- }
- }
- }
-
- // Improper expression
- if ( expr == old ) {
- if ( anyFound == null ) {
- throw "Syntax error, unrecognized expression: " + expr;
- } else {
- break;
- }
- }
-
- old = expr;
- }
-
- return curLoop;
-};
-
-/**#@+ @ignore */
-var Expr = Sizzle.selectors = {
- order: [ "ID", "NAME", "TAG" ],
- match: {
- ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
- CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
- NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
- ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
- TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
- CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
- POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
- PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
- },
- leftMatch: {},
- attrMap: {
- "class": "className",
- "for": "htmlFor"
- },
- attrHandle: {
- href: function(elem){
- return elem.getAttribute("href");
- }
- },
- relative: {
- "+": function(checkSet, part, isXML){
- var isPartStr = typeof part === "string",
- isTag = isPartStr && !/\W/.test(part),
- isPartStrNotTag = isPartStr && !isTag;
-
- if ( isTag && !isXML ) {
- part = part.toUpperCase();
- }
-
- for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
- if ( (elem = checkSet[i]) ) {
- while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
-
- checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
- elem || false :
- elem === part;
- }
- }
-
- if ( isPartStrNotTag ) {
- Sizzle.filter( part, checkSet, true );
- }
- },
- ">": function(checkSet, part, isXML){
- var isPartStr = typeof part === "string";
-
- if ( isPartStr && !/\W/.test(part) ) {
- part = isXML ? part : part.toUpperCase();
-
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
- if ( elem ) {
- var parent = elem.parentNode;
- checkSet[i] = parent.nodeName === part ? parent : false;
- }
- }
- } else {
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
- if ( elem ) {
- checkSet[i] = isPartStr ?
- elem.parentNode :
- elem.parentNode === part;
- }
- }
-
- if ( isPartStr ) {
- Sizzle.filter( part, checkSet, true );
- }
- }
- },
- "": function(checkSet, part, isXML){
- var doneName = done++, checkFn = dirCheck;
-
- if ( !/\W/.test(part) ) {
- var nodeCheck = part = isXML ? part : part.toUpperCase();
- checkFn = dirNodeCheck;
- }
-
- checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
- },
- "~": function(checkSet, part, isXML){
- var doneName = done++, checkFn = dirCheck;
-
- if ( typeof part === "string" && !/\W/.test(part) ) {
- var nodeCheck = part = isXML ? part : part.toUpperCase();
- checkFn = dirNodeCheck;
- }
-
- checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
- }
- },
- find: {
- ID: function(match, context, isXML){
- if ( typeof context.getElementById !== "undefined" && !isXML ) {
- var m = context.getElementById(match[1]);
- return m ? [m] : [];
- }
- },
- NAME: function(match, context, isXML){
- if ( typeof context.getElementsByName !== "undefined" ) {
- var ret = [], results = context.getElementsByName(match[1]);
-
- for ( var i = 0, l = results.length; i < l; i++ ) {
- if ( results[i].getAttribute("name") === match[1] ) {
- ret.push( results[i] );
- }
- }
-
- return ret.length === 0 ? null : ret;
- }
- },
- TAG: function(match, context){
- return context.getElementsByTagName(match[1]);
- }
- },
- preFilter: {
- CLASS: function(match, curLoop, inplace, result, not, isXML){
- match = " " + match[1].replace(/\\/g, "") + " ";
-
- if ( isXML ) {
- return match;
- }
-
- for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
- if ( elem ) {
- if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
- if ( !inplace )
- result.push( elem );
- } else if ( inplace ) {
- curLoop[i] = false;
- }
- }
- }
-
- return false;
- },
- ID: function(match){
- return match[1].replace(/\\/g, "");
- },
- TAG: function(match, curLoop){
- for ( var i = 0; curLoop[i] === false; i++ ){}
- return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
- },
- CHILD: function(match){
- if ( match[1] == "nth" ) {
- // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
- var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
- match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
- !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
-
- // calculate the numbers (first)n+(last) including if they are negative
- match[2] = (test[1] + (test[2] || 1)) - 0;
- match[3] = test[3] - 0;
- }
-
- // TODO: Move to normal caching system
- match[0] = done++;
-
- return match;
- },
- ATTR: function(match, curLoop, inplace, result, not, isXML){
- var name = match[1].replace(/\\/g, "");
-
- if ( !isXML && Expr.attrMap[name] ) {
- match[1] = Expr.attrMap[name];
- }
-
- if ( match[2] === "~=" ) {
- match[4] = " " + match[4] + " ";
- }
-
- return match;
- },
- PSEUDO: function(match, curLoop, inplace, result, not){
- if ( match[1] === "not" ) {
- // If we're dealing with a complex expression, or a simple one
- if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
- match[3] = Sizzle(match[3], null, null, curLoop);
- } else {
- var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
- if ( !inplace ) {
- result.push.apply( result, ret );
- }
- return false;
- }
- } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
- return true;
- }
-
- return match;
- },
- POS: function(match){
- match.unshift( true );
- return match;
- }
- },
- filters: {
- enabled: function(elem){
- return elem.disabled === false && elem.type !== "hidden";
- },
- disabled: function(elem){
- return elem.disabled === true;
- },
- checked: function(elem){
- return elem.checked === true;
- },
- selected: function(elem){
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- elem.parentNode.selectedIndex;
- return elem.selected === true;
- },
- parent: function(elem){
- return !!elem.firstChild;
- },
- empty: function(elem){
- return !elem.firstChild;
- },
- has: function(elem, i, match){
- return !!Sizzle( match[3], elem ).length;
- },
- header: function(elem){
- return /h\d/i.test( elem.nodeName );
- },
- text: function(elem){
- return "text" === elem.type;
- },
- radio: function(elem){
- return "radio" === elem.type;
- },
- checkbox: function(elem){
- return "checkbox" === elem.type;
- },
- file: function(elem){
- return "file" === elem.type;
- },
- password: function(elem){
- return "password" === elem.type;
- },
- submit: function(elem){
- return "submit" === elem.type;
- },
- image: function(elem){
- return "image" === elem.type;
- },
- reset: function(elem){
- return "reset" === elem.type;
- },
- button: function(elem){
- return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
- },
- input: function(elem){
- return /input|select|textarea|button/i.test(elem.nodeName);
- }
- },
- setFilters: {
- first: function(elem, i){
- return i === 0;
- },
- last: function(elem, i, match, array){
- return i === array.length - 1;
- },
- even: function(elem, i){
- return i % 2 === 0;
- },
- odd: function(elem, i){
- return i % 2 === 1;
- },
- lt: function(elem, i, match){
- return i < match[3] - 0;
- },
- gt: function(elem, i, match){
- return i > match[3] - 0;
- },
- nth: function(elem, i, match){
- return match[3] - 0 == i;
- },
- eq: function(elem, i, match){
- return match[3] - 0 == i;
- }
- },
- filter: {
- PSEUDO: function(elem, match, i, array){
- var name = match[1], filter = Expr.filters[ name ];
-
- if ( filter ) {
- return filter( elem, i, match, array );
- } else if ( name === "contains" ) {
- return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
- } else if ( name === "not" ) {
- var not = match[3];
-
- for ( var i = 0, l = not.length; i < l; i++ ) {
- if ( not[i] === elem ) {
- return false;
- }
- }
-
- return true;
- }
- },
- CHILD: function(elem, match){
- var type = match[1], node = elem;
- switch (type) {
- case 'only':
- case 'first':
- while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) return false;
- }
- if ( type == 'first') return true;
- node = elem;
- case 'last':
- while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) return false;
- }
- return true;
- case 'nth':
- var first = match[2], last = match[3];
-
- if ( first == 1 && last == 0 ) {
- return true;
- }
-
- var doneName = match[0],
- parent = elem.parentNode;
-
- if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
- var count = 0;
- for ( node = parent.firstChild; node; node = node.nextSibling ) {
- if ( node.nodeType === 1 ) {
- node.nodeIndex = ++count;
- }
- }
- parent.sizcache = doneName;
- }
-
- var diff = elem.nodeIndex - last;
- if ( first == 0 ) {
- return diff == 0;
- } else {
- return ( diff % first == 0 && diff / first >= 0 );
- }
- }
- },
- ID: function(elem, match){
- return elem.nodeType === 1 && elem.getAttribute("id") === match;
- },
- TAG: function(elem, match){
- return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
- },
- CLASS: function(elem, match){
- return (" " + (elem.className || elem.getAttribute("class")) + " ")
- .indexOf( match ) > -1;
- },
- ATTR: function(elem, match){
- var name = match[1],
- result = Expr.attrHandle[ name ] ?
- Expr.attrHandle[ name ]( elem ) :
- elem[ name ] != null ?
- elem[ name ] :
- elem.getAttribute( name ),
- value = result + "",
- type = match[2],
- check = match[4];
-
- return result == null ?
- type === "!=" :
- type === "=" ?
- value === check :
- type === "*=" ?
- value.indexOf(check) >= 0 :
- type === "~=" ?
- (" " + value + " ").indexOf(check) >= 0 :
- !check ?
- value && result !== false :
- type === "!=" ?
- value != check :
- type === "^=" ?
- value.indexOf(check) === 0 :
- type === "$=" ?
- value.substr(value.length - check.length) === check :
- type === "|=" ?
- value === check || value.substr(0, check.length + 1) === check + "-" :
- false;
- },
- POS: function(elem, match, i, array){
- var name = match[2], filter = Expr.setFilters[ name ];
-
- if ( filter ) {
- return filter( elem, i, match, array );
- }
- }
- }
-};
-
-var origPOS = Expr.match.POS;
-
-for ( var type in Expr.match ) {
- Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
- Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source );
-}
-
-var makeArray = function(array, results) {
- array = Array.prototype.slice.call( array, 0 );
-
- if ( results ) {
- results.push.apply( results, array );
- return results;
- }
-
- return array;
-};
-
-// Perform a simple check to determine if the browser is capable of
-// converting a NodeList to an array using builtin methods.
-try {
- Array.prototype.slice.call( document.documentElement.childNodes, 0 );
-
-// Provide a fallback method if it does not work
-} catch(e){
- makeArray = function(array, results) {
- var ret = results || [];
-
- if ( toString.call(array) === "[object Array]" ) {
- Array.prototype.push.apply( ret, array );
- } else {
- if ( typeof array.length === "number" ) {
- for ( var i = 0, l = array.length; i < l; i++ ) {
- ret.push( array[i] );
- }
- } else {
- for ( var i = 0; array[i]; i++ ) {
- ret.push( array[i] );
- }
- }
- }
-
- return ret;
- };
-}
-
-var sortOrder;
-
-if ( document.documentElement.compareDocumentPosition ) {
- sortOrder = function( a, b ) {
- if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
- if ( a == b ) {
- hasDuplicate = true;
- }
- return 0;
- }
-
- var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
- if ( ret === 0 ) {
- hasDuplicate = true;
- }
- return ret;
- };
-} else if ( "sourceIndex" in document.documentElement ) {
- sortOrder = function( a, b ) {
- if ( !a.sourceIndex || !b.sourceIndex ) {
- if ( a == b ) {
- hasDuplicate = true;
- }
- return 0;
- }
-
- var ret = a.sourceIndex - b.sourceIndex;
- if ( ret === 0 ) {
- hasDuplicate = true;
- }
- return ret;
- };
-} else if ( document.createRange ) {
- sortOrder = function( a, b ) {
- if ( !a.ownerDocument || !b.ownerDocument ) {
- if ( a == b ) {
- hasDuplicate = true;
- }
- return 0;
- }
-
- var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
- aRange.setStart(a, 0);
- aRange.setEnd(a, 0);
- bRange.setStart(b, 0);
- bRange.setEnd(b, 0);
- var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
- if ( ret === 0 ) {
- hasDuplicate = true;
- }
- return ret;
- };
-}
-
-// Check to see if the browser returns elements by name when
-// querying by getElementById (and provide a workaround)
-(function(){
- // We're going to inject a fake input element with a specified name
- var form = document.createElement("div"),
- id = "script" + (new Date).getTime();
- form.innerHTML = "<a name='" + id + "'/>";
-
- // Inject it into the root element, check its status, and remove it quickly
- var root = document.documentElement;
- root.insertBefore( form, root.firstChild );
-
- // The workaround has to do additional checks after a getElementById
- // Which slows things down for other browsers (hence the branching)
- if ( !!document.getElementById( id ) ) {
- Expr.find.ID = function(match, context, isXML){
- if ( typeof context.getElementById !== "undefined" && !isXML ) {
- var m = context.getElementById(match[1]);
- return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
- }
- };
-
- Expr.filter.ID = function(elem, match){
- var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
- return elem.nodeType === 1 && node && node.nodeValue === match;
- };
- }
-
- root.removeChild( form );
- root = form = null; // release memory in IE
-})();
-
-(function(){
- // Check to see if the browser returns only elements
- // when doing getElementsByTagName("*")
-
- // Create a fake element
- var div = document.createElement("div");
- div.appendChild( document.createComment("") );
-
- // Make sure no comments are found
- if ( div.getElementsByTagName("*").length > 0 ) {
- Expr.find.TAG = function(match, context){
- var results = context.getElementsByTagName(match[1]);
-
- // Filter out possible comments
- if ( match[1] === "*" ) {
- var tmp = [];
-
- for ( var i = 0; results[i]; i++ ) {
- if ( results[i].nodeType === 1 ) {
- tmp.push( results[i] );
- }
- }
-
- results = tmp;
- }
-
- return results;
- };
- }
-
- // Check to see if an attribute returns normalized href attributes
- div.innerHTML = "<a href='#'></a>";
- if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
- div.firstChild.getAttribute("href") !== "#" ) {
- Expr.attrHandle.href = function(elem){
- return elem.getAttribute("href", 2);
- };
- }
-
- div = null; // release memory in IE
-})();
-
-if ( document.querySelectorAll ) (function(){
- var oldSizzle = Sizzle, div = document.createElement("div");
- div.innerHTML = "<p class='TEST'></p>";
-
- // Safari can't handle uppercase or unicode characters when
- // in quirks mode.
- if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
- return;
- }
-
- Sizzle = function(query, context, extra, seed){
- context = context || document;
-
- // Only use querySelectorAll on non-XML documents
- // (ID selectors don't work in non-HTML documents)
- if ( !seed && context.nodeType === 9 && !isXML(context) ) {
- try {
- return makeArray( context.querySelectorAll(query), extra );
- } catch(e){}
- }
-
- return oldSizzle(query, context, extra, seed);
- };
-
- for ( var prop in oldSizzle ) {
- Sizzle[ prop ] = oldSizzle[ prop ];
- }
-
- div = null; // release memory in IE
-})();
-
-if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
- var div = document.createElement("div");
- div.innerHTML = "<div class='test e'></div><div class='test'></div>";
-
- // Opera can't find a second classname (in 9.6)
- if ( div.getElementsByClassName("e").length === 0 )
- return;
-
- // Safari caches class attributes, doesn't catch changes (in 3.2)
- div.lastChild.className = "e";
-
- if ( div.getElementsByClassName("e").length === 1 )
- return;
-
- Expr.order.splice(1, 0, "CLASS");
- Expr.find.CLASS = function(match, context, isXML) {
- if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
- return context.getElementsByClassName(match[1]);
- }
- };
-
- div = null; // release memory in IE
-})();
-
-function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
- var sibDir = dir == "previousSibling" && !isXML;
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
- if ( elem ) {
- if ( sibDir && elem.nodeType === 1 ){
- elem.sizcache = doneName;
- elem.sizset = i;
- }
- elem = elem[dir];
- var match = false;
-
- while ( elem ) {
- if ( elem.sizcache === doneName ) {
- match = checkSet[elem.sizset];
- break;
- }
-
- if ( elem.nodeType === 1 && !isXML ){
- elem.sizcache = doneName;
- elem.sizset = i;
- }
-
- if ( elem.nodeName === cur ) {
- match = elem;
- break;
- }
-
- elem = elem[dir];
- }
-
- checkSet[i] = match;
- }
- }
-}
-
-function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
- var sibDir = dir == "previousSibling" && !isXML;
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
- if ( elem ) {
- if ( sibDir && elem.nodeType === 1 ) {
- elem.sizcache = doneName;
- elem.sizset = i;
- }
- elem = elem[dir];
- var match = false;
-
- while ( elem ) {
- if ( elem.sizcache === doneName ) {
- match = checkSet[elem.sizset];
- break;
- }
-
- if ( elem.nodeType === 1 ) {
- if ( !isXML ) {
- elem.sizcache = doneName;
- elem.sizset = i;
- }
- if ( typeof cur !== "string" ) {
- if ( elem === cur ) {
- match = true;
- break;
- }
-
- } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
- match = elem;
- break;
- }
- }
-
- elem = elem[dir];
- }
-
- checkSet[i] = match;
- }
- }
-}
-
-var contains = document.compareDocumentPosition ? function(a, b){
- return a.compareDocumentPosition(b) & 16;
-} : function(a, b){
- return a !== b && (a.contains ? a.contains(b) : true);
-};
-
-var isXML = function(elem){
- return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
- !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
-};
-
-var posProcess = function(selector, context){
- var tmpSet = [], later = "", match,
- root = context.nodeType ? [context] : context;
-
- // Position selectors must be done after the filter
- // And so must :not(positional) so we move all PSEUDOs to the end
- while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
- later += match[0];
- selector = selector.replace( Expr.match.PSEUDO, "" );
- }
-
- selector = Expr.relative[selector] ? selector + "*" : selector;
-
- for ( var i = 0, l = root.length; i < l; i++ ) {
- Sizzle( selector, root[i], tmpSet );
- }
-
- return Sizzle.filter( later, tmpSet );
-};
-
-// EXPOSE
-
-Firebug.Selector = Sizzle;
-
-/**#@-*/
-
-// ************************************************************************************************
-}});
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-// ************************************************************************************************
-// Inspector Module
-
-var ElementCache = Firebug.Lite.Cache.Element;
-
-var inspectorTS, inspectorTimer, isInspecting;
-
-Firebug.Inspector =
-{
- create: function()
- {
- offlineFragment = Env.browser.document.createDocumentFragment();
-
- createBoxModelInspector();
- createOutlineInspector();
- },
-
- destroy: function()
- {
- destroyBoxModelInspector();
- destroyOutlineInspector();
-
- offlineFragment = null;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Inspect functions
-
- toggleInspect: function()
- {
- if (isInspecting)
- {
- this.stopInspecting();
- }
- else
- {
- Firebug.chrome.inspectButton.changeState("pressed");
- this.startInspecting();
- }
- },
-
- startInspecting: function()
- {
- isInspecting = true;
-
- Firebug.chrome.selectPanel("HTML");
-
- createInspectorFrame();
-
- var size = Firebug.browser.getWindowScrollSize();
-
- fbInspectFrame.style.width = size.width + "px";
- fbInspectFrame.style.height = size.height + "px";
-
- //addEvent(Firebug.browser.document.documentElement, "mousemove", Firebug.Inspector.onInspectingBody);
-
- addEvent(fbInspectFrame, "mousemove", Firebug.Inspector.onInspecting);
- addEvent(fbInspectFrame, "mousedown", Firebug.Inspector.onInspectingClick);
- },
-
- stopInspecting: function()
- {
- isInspecting = false;
-
- if (outlineVisible) this.hideOutline();
- removeEvent(fbInspectFrame, "mousemove", Firebug.Inspector.onInspecting);
- removeEvent(fbInspectFrame, "mousedown", Firebug.Inspector.onInspectingClick);
-
- destroyInspectorFrame();
-
- Firebug.chrome.inspectButton.restore();
-
- if (Firebug.chrome.type == "popup")
- Firebug.chrome.node.focus();
- },
-
- onInspectingClick: function(e)
- {
- fbInspectFrame.style.display = "none";
- var targ = Firebug.browser.getElementFromPoint(e.clientX, e.clientY);
- fbInspectFrame.style.display = "block";
-
- // Avoid inspecting the outline, and the FirebugUI
- var id = targ.id;
- if (id && /^fbOutline\w$/.test(id)) return;
- if (id == "FirebugUI") return;
-
- // Avoid looking at text nodes in Opera
- while (targ.nodeType != 1) targ = targ.parentNode;
-
- //Firebug.Console.log(targ);
- Firebug.Inspector.stopInspecting();
- },
-
- onInspecting: function(e)
- {
- if (new Date().getTime() - lastInspecting > 30)
- {
- fbInspectFrame.style.display = "none";
- var targ = Firebug.browser.getElementFromPoint(e.clientX, e.clientY);
- fbInspectFrame.style.display = "block";
-
- // Avoid inspecting the outline, and the FirebugUI
- var id = targ.id;
- if (id && /^fbOutline\w$/.test(id)) return;
- if (id == "FirebugUI") return;
-
- // Avoid looking at text nodes in Opera
- while (targ.nodeType != 1) targ = targ.parentNode;
-
- if (targ.nodeName.toLowerCase() == "body") return;
-
- //Firebug.Console.log(e.clientX, e.clientY, targ);
- Firebug.Inspector.drawOutline(targ);
-
- if (ElementCache(targ))
- {
- var target = ""+ElementCache.key(targ);
- var lazySelect = function()
- {
- inspectorTS = new Date().getTime();
-
- if (Firebug.HTML)
- Firebug.HTML.selectTreeNode(""+ElementCache.key(targ));
- };
-
- if (inspectorTimer)
- {
- clearTimeout(inspectorTimer);
- inspectorTimer = null;
- }
-
- if (new Date().getTime() - inspectorTS > 200)
- setTimeout(lazySelect, 0);
- else
- inspectorTimer = setTimeout(lazySelect, 300);
- }
-
- lastInspecting = new Date().getTime();
- }
- },
-
- // TODO: xxxpedro remove this?
- onInspectingBody: function(e)
- {
- if (new Date().getTime() - lastInspecting > 30)
- {
- var targ = e.target;
-
- // Avoid inspecting the outline, and the FirebugUI
- var id = targ.id;
- if (id && /^fbOutline\w$/.test(id)) return;
- if (id == "FirebugUI") return;
-
- // Avoid looking at text nodes in Opera
- while (targ.nodeType != 1) targ = targ.parentNode;
-
- if (targ.nodeName.toLowerCase() == "body") return;
-
- //Firebug.Console.log(e.clientX, e.clientY, targ);
- Firebug.Inspector.drawOutline(targ);
-
- if (ElementCache.has(targ))
- FBL.Firebug.HTML.selectTreeNode(""+ElementCache.key(targ));
-
- lastInspecting = new Date().getTime();
- }
- },
-
- /**
- *
- * llttttttrr
- * llttttttrr
- * ll rr
- * ll rr
- * llbbbbbbrr
- * llbbbbbbrr
- */
- drawOutline: function(el)
- {
- var border = 2;
- var scrollbarSize = 17;
-
- var windowSize = Firebug.browser.getWindowSize();
- var scrollSize = Firebug.browser.getWindowScrollSize();
- var scrollPosition = Firebug.browser.getWindowScrollPosition();
-
- var box = Firebug.browser.getElementBox(el);
-
- var top = box.top;
- var left = box.left;
- var height = box.height;
- var width = box.width;
-
- var freeHorizontalSpace = scrollPosition.left + windowSize.width - left - width -
- (!isIE && scrollSize.height > windowSize.height ? // is *vertical* scrollbar visible
- scrollbarSize : 0);
-
- var freeVerticalSpace = scrollPosition.top + windowSize.height - top - height -
- (!isIE && scrollSize.width > windowSize.width ? // is *horizontal* scrollbar visible
- scrollbarSize : 0);
-
- var numVerticalBorders = freeVerticalSpace > 0 ? 2 : 1;
-
- var o = outlineElements;
- var style;
-
- style = o.fbOutlineT.style;
- style.top = top-border + "px";
- style.left = left + "px";
- style.height = border + "px"; // TODO: on initialize()
- style.width = width + "px";
-
- style = o.fbOutlineL.style;
- style.top = top-border + "px";
- style.left = left-border + "px";
- style.height = height+ numVerticalBorders*border + "px";
- style.width = border + "px"; // TODO: on initialize()
-
- style = o.fbOutlineB.style;
- if (freeVerticalSpace > 0)
- {
- style.top = top+height + "px";
- style.left = left + "px";
- style.width = width + "px";
- //style.height = border + "px"; // TODO: on initialize() or worst case?
- }
- else
- {
- style.top = -2*border + "px";
- style.left = -2*border + "px";
- style.width = border + "px";
- //style.height = border + "px";
- }
-
- style = o.fbOutlineR.style;
- if (freeHorizontalSpace > 0)
- {
- style.top = top-border + "px";
- style.left = left+width + "px";
- style.height = height + numVerticalBorders*border + "px";
- style.width = (freeHorizontalSpace < border ? freeHorizontalSpace : border) + "px";
- }
- else
- {
- style.top = -2*border + "px";
- style.left = -2*border + "px";
- style.height = border + "px";
- style.width = border + "px";
- }
-
- if (!outlineVisible) this.showOutline();
- },
-
- hideOutline: function()
- {
- if (!outlineVisible) return;
-
- for (var name in outline)
- offlineFragment.appendChild(outlineElements[name]);
-
- outlineVisible = false;
- },
-
- showOutline: function()
- {
- if (outlineVisible) return;
-
- if (boxModelVisible) this.hideBoxModel();
-
- for (var name in outline)
- Firebug.browser.document.getElementsByTagName("body")[0].appendChild(outlineElements[name]);
-
- outlineVisible = true;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Box Model
-
- drawBoxModel: function(el)
- {
- // avoid error when the element is not attached a document
- if (!el || !el.parentNode)
- return;
-
- var box = Firebug.browser.getElementBox(el);
-
- var windowSize = Firebug.browser.getWindowSize();
- var scrollPosition = Firebug.browser.getWindowScrollPosition();
-
- // element may be occluded by the chrome, when in frame mode
- var offsetHeight = Firebug.chrome.type == "frame" ? Firebug.context.persistedState.height : 0;
-
- // if element box is not inside the viewport, don't draw the box model
- if (box.top > scrollPosition.top + windowSize.height - offsetHeight ||
- box.left > scrollPosition.left + windowSize.width ||
- scrollPosition.top > box.top + box.height ||
- scrollPosition.left > box.left + box.width )
- return;
-
- var top = box.top;
- var left = box.left;
- var height = box.height;
- var width = box.width;
-
- var margin = Firebug.browser.getMeasurementBox(el, "margin");
- var padding = Firebug.browser.getMeasurementBox(el, "padding");
- var border = Firebug.browser.getMeasurementBox(el, "border");
-
- boxModelStyle.top = top - margin.top + "px";
- boxModelStyle.left = left - margin.left + "px";
- boxModelStyle.height = height + margin.top + margin.bottom + "px";
- boxModelStyle.width = width + margin.left + margin.right + "px";
-
- boxBorderStyle.top = margin.top + "px";
- boxBorderStyle.left = margin.left + "px";
- boxBorderStyle.height = height + "px";
- boxBorderStyle.width = width + "px";
-
- boxPaddingStyle.top = margin.top + border.top + "px";
- boxPaddingStyle.left = margin.left + border.left + "px";
- boxPaddingStyle.height = height - border.top - border.bottom + "px";
- boxPaddingStyle.width = width - border.left - border.right + "px";
-
- boxContentStyle.top = margin.top + border.top + padding.top + "px";
- boxContentStyle.left = margin.left + border.left + padding.left + "px";
- boxContentStyle.height = height - border.top - padding.top - padding.bottom - border.bottom + "px";
- boxContentStyle.width = width - border.left - padding.left - padding.right - border.right + "px";
-
- if (!boxModelVisible) this.showBoxModel();
- },
-
- hideBoxModel: function()
- {
- if (!boxModelVisible) return;
-
- offlineFragment.appendChild(boxModel);
- boxModelVisible = false;
- },
-
- showBoxModel: function()
- {
- if (boxModelVisible) return;
-
- if (outlineVisible) this.hideOutline();
-
- Firebug.browser.document.getElementsByTagName("body")[0].appendChild(boxModel);
- boxModelVisible = true;
- }
-
-};
-
-// ************************************************************************************************
-// Inspector Internals
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// Shared variables
-
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// Internal variables
-
-var offlineFragment = null;
-
-var boxModelVisible = false;
-
-var boxModel, boxModelStyle,
- boxMargin, boxMarginStyle,
- boxBorder, boxBorderStyle,
- boxPadding, boxPaddingStyle,
- boxContent, boxContentStyle;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var resetStyle = "margin:0; padding:0; border:0; position:absolute; overflow:hidden; display:block;";
-var offscreenStyle = resetStyle + "top:-1234px; left:-1234px;";
-
-var inspectStyle = resetStyle + "z-index: 2147483500;";
-var inspectFrameStyle = resetStyle + "z-index: 2147483550; top:0; left:0; background:url(" +
- Env.Location.skinDir + "pixel_transparent.gif);";
-
-//if (Env.Options.enableTrace) inspectFrameStyle = resetStyle + "z-index: 2147483550; top: 0; left: 0; background: #ff0; opacity: 0.05; _filter: alpha(opacity=5);";
-
-var inspectModelOpacity = isIE ? "filter:alpha(opacity=80);" : "opacity:0.8;";
-var inspectModelStyle = inspectStyle + inspectModelOpacity;
-var inspectMarginStyle = inspectStyle + "background: #EDFF64; height:100%; width:100%;";
-var inspectBorderStyle = inspectStyle + "background: #666;";
-var inspectPaddingStyle = inspectStyle + "background: SlateBlue;";
-var inspectContentStyle = inspectStyle + "background: SkyBlue;";
-
-
-var outlineStyle = {
- fbHorizontalLine: "background: #3875D7;height: 2px;",
- fbVerticalLine: "background: #3875D7;width: 2px;"
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var lastInspecting = 0;
-var fbInspectFrame = null;
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var outlineVisible = false;
-var outlineElements = {};
-var outline = {
- "fbOutlineT": "fbHorizontalLine",
- "fbOutlineL": "fbVerticalLine",
- "fbOutlineB": "fbHorizontalLine",
- "fbOutlineR": "fbVerticalLine"
-};
-
-
-var getInspectingTarget = function()
-{
-
-};
-
-// ************************************************************************************************
-// Section
-
-var createInspectorFrame = function createInspectorFrame()
-{
- fbInspectFrame = createGlobalElement("div");
- fbInspectFrame.id = "fbInspectFrame";
- fbInspectFrame.firebugIgnore = true;
- fbInspectFrame.style.cssText = inspectFrameStyle;
- Firebug.browser.document.getElementsByTagName("body")[0].appendChild(fbInspectFrame);
-};
-
-var destroyInspectorFrame = function destroyInspectorFrame()
-{
- if (fbInspectFrame)
- {
- Firebug.browser.document.getElementsByTagName("body")[0].removeChild(fbInspectFrame);
- fbInspectFrame = null;
- }
-};
-
-var createOutlineInspector = function createOutlineInspector()
-{
- for (var name in outline)
- {
- var el = outlineElements[name] = createGlobalElement("div");
- el.id = name;
- el.firebugIgnore = true;
- el.style.cssText = inspectStyle + outlineStyle[outline[name]];
- offlineFragment.appendChild(el);
- }
-};
-
-var destroyOutlineInspector = function destroyOutlineInspector()
-{
- for (var name in outline)
- {
- var el = outlineElements[name];
- el.parentNode.removeChild(el);
- }
-};
-
-var createBoxModelInspector = function createBoxModelInspector()
-{
- boxModel = createGlobalElement("div");
- boxModel.id = "fbBoxModel";
- boxModel.firebugIgnore = true;
- boxModelStyle = boxModel.style;
- boxModelStyle.cssText = inspectModelStyle;
-
- boxMargin = createGlobalElement("div");
- boxMargin.id = "fbBoxMargin";
- boxMarginStyle = boxMargin.style;
- boxMarginStyle.cssText = inspectMarginStyle;
- boxModel.appendChild(boxMargin);
-
- boxBorder = createGlobalElement("div");
- boxBorder.id = "fbBoxBorder";
- boxBorderStyle = boxBorder.style;
- boxBorderStyle.cssText = inspectBorderStyle;
- boxModel.appendChild(boxBorder);
-
- boxPadding = createGlobalElement("div");
- boxPadding.id = "fbBoxPadding";
- boxPaddingStyle = boxPadding.style;
- boxPaddingStyle.cssText = inspectPaddingStyle;
- boxModel.appendChild(boxPadding);
-
- boxContent = createGlobalElement("div");
- boxContent.id = "fbBoxContent";
- boxContentStyle = boxContent.style;
- boxContentStyle.cssText = inspectContentStyle;
- boxModel.appendChild(boxContent);
-
- offlineFragment.appendChild(boxModel);
-};
-
-var destroyBoxModelInspector = function destroyBoxModelInspector()
-{
- boxModel.parentNode.removeChild(boxModel);
-};
-
-// ************************************************************************************************
-// Section
-
-
-
-
-// ************************************************************************************************
-}});
-
-// Problems in IE
-// FIXED - eval return
-// FIXED - addEventListener problem in IE
-// FIXED doc.createRange?
-//
-// class reserved word
-// test all honza examples in IE6 and IE7
-
-
-/* See license.txt for terms of usage */
-
-( /** @scope s_domplate */ function() {
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-/** @class */
-FBL.DomplateTag = function DomplateTag(tagName)
-{
- this.tagName = tagName;
-};
-
-/**
- * @class
- * @extends FBL.DomplateTag
- */
-FBL.DomplateEmbed = function DomplateEmbed()
-{
-};
-
-/**
- * @class
- * @extends FBL.DomplateTag
- */
-FBL.DomplateLoop = function DomplateLoop()
-{
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var DomplateTag = FBL.DomplateTag;
-var DomplateEmbed = FBL.DomplateEmbed;
-var DomplateLoop = FBL.DomplateLoop;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var womb = null;
-
-FBL.domplate = function()
-{
- var lastSubject;
- for (var i = 0; i < arguments.length; ++i)
- lastSubject = lastSubject ? copyObject(lastSubject, arguments[i]) : arguments[i];
-
- for (var name in lastSubject)
- {
- var val = lastSubject[name];
- if (isTag(val))
- val.tag.subject = lastSubject;
- }
-
- return lastSubject;
-};
-
-var domplate = FBL.domplate;
-
-FBL.domplate.context = function(context, fn)
-{
- var lastContext = domplate.lastContext;
- domplate.topContext = context;
- fn.apply(context);
- domplate.topContext = lastContext;
-};
-
-FBL.TAG = function()
-{
- var embed = new DomplateEmbed();
- return embed.merge(arguments);
-};
-
-FBL.FOR = function()
-{
- var loop = new DomplateLoop();
- return loop.merge(arguments);
-};
-
-FBL.DomplateTag.prototype =
-{
- merge: function(args, oldTag)
- {
- if (oldTag)
- this.tagName = oldTag.tagName;
-
- this.context = oldTag ? oldTag.context : null;
- this.subject = oldTag ? oldTag.subject : null;
- this.attrs = oldTag ? copyObject(oldTag.attrs) : {};
- this.classes = oldTag ? copyObject(oldTag.classes) : {};
- this.props = oldTag ? copyObject(oldTag.props) : null;
- this.listeners = oldTag ? copyArray(oldTag.listeners) : null;
- this.children = oldTag ? copyArray(oldTag.children) : [];
- this.vars = oldTag ? copyArray(oldTag.vars) : [];
-
- var attrs = args.length ? args[0] : null;
- var hasAttrs = typeof(attrs) == "object" && !isTag(attrs);
-
- this.children = [];
-
- if (domplate.topContext)
- this.context = domplate.topContext;
-
- if (args.length)
- parseChildren(args, hasAttrs ? 1 : 0, this.vars, this.children);
-
- if (hasAttrs)
- this.parseAttrs(attrs);
-
- return creator(this, DomplateTag);
- },
-
- parseAttrs: function(args)
- {
- for (var name in args)
- {
- var val = parseValue(args[name]);
- readPartNames(val, this.vars);
-
- if (name.indexOf("on") == 0)
- {
- var eventName = name.substr(2);
- if (!this.listeners)
- this.listeners = [];
- this.listeners.push(eventName, val);
- }
- else if (name.indexOf("_") == 0)
- {
- var propName = name.substr(1);
- if (!this.props)
- this.props = {};
- this.props[propName] = val;
- }
- else if (name.indexOf("$") == 0)
- {
- var className = name.substr(1);
- if (!this.classes)
- this.classes = {};
- this.classes[className] = val;
- }
- else
- {
- if (name == "class" && this.attrs.hasOwnProperty(name) )
- this.attrs[name] += " " + val;
- else
- this.attrs[name] = val;
- }
- }
- },
-
- compile: function()
- {
- if (this.renderMarkup)
- return;
-
- this.compileMarkup();
- this.compileDOM();
-
- //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderMarkup: ", this.renderMarkup);
- //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderDOM:", this.renderDOM);
- //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate domArgs:", this.domArgs);
- },
-
- compileMarkup: function()
- {
- this.markupArgs = [];
- var topBlock = [], topOuts = [], blocks = [], info = {args: this.markupArgs, argIndex: 0};
-
- this.generateMarkup(topBlock, topOuts, blocks, info);
- this.addCode(topBlock, topOuts, blocks);
-
- var fnBlock = ['r=(function (__code__, __context__, __in__, __out__'];
- for (var i = 0; i < info.argIndex; ++i)
- fnBlock.push(', s', i);
- fnBlock.push(') {');
-
- if (this.subject)
- fnBlock.push('with (this) {');
- if (this.context)
- fnBlock.push('with (__context__) {');
- fnBlock.push('with (__in__) {');
-
- fnBlock.push.apply(fnBlock, blocks);
-
- if (this.subject)
- fnBlock.push('}');
- if (this.context)
- fnBlock.push('}');
-
- fnBlock.push('}})');
-
- function __link__(tag, code, outputs, args)
- {
- if (!tag || !tag.tag)
- return;
-
- tag.tag.compile();
-
- var tagOutputs = [];
- var markupArgs = [code, tag.tag.context, args, tagOutputs];
- markupArgs.push.apply(markupArgs, tag.tag.markupArgs);
- tag.tag.renderMarkup.apply(tag.tag.subject, markupArgs);
-
- outputs.push(tag);
- outputs.push(tagOutputs);
- }
-
- function __escape__(value)
- {
- function replaceChars(ch)
- {
- switch (ch)
- {
- case "<":
- return "&lt;";
- case ">":
- return "&gt;";
- case "&":
- return "&amp;";
- case "'":
- return "&#39;";
- case '"':
- return "&quot;";
- }
- return "?";
- };
- return String(value).replace(/[<>&"']/g, replaceChars);
- }
-
- function __loop__(iter, outputs, fn)
- {
- var iterOuts = [];
- outputs.push(iterOuts);
-
- if (iter instanceof Array)
- iter = new ArrayIterator(iter);
-
- try
- {
- while (1)
- {
- var value = iter.next();
- var itemOuts = [0,0];
- iterOuts.push(itemOuts);
- fn.apply(this, [value, itemOuts]);
- }
- }
- catch (exc)
- {
- if (exc != StopIteration)
- throw exc;
- }
- }
-
- var js = fnBlock.join("");
- var r = null;
- eval(js);
- this.renderMarkup = r;
- },
-
- getVarNames: function(args)
- {
- if (this.vars)
- args.push.apply(args, this.vars);
-
- for (var i = 0; i < this.children.length; ++i)
- {
- var child = this.children[i];
- if (isTag(child))
- child.tag.getVarNames(args);
- else if (child instanceof Parts)
- {
- for (var i = 0; i < child.parts.length; ++i)
- {
- if (child.parts[i] instanceof Variable)
- {
- var name = child.parts[i].name;
- var names = name.split(".");
- args.push(names[0]);
- }
- }
- }
- }
- },
-
- generateMarkup: function(topBlock, topOuts, blocks, info)
- {
- topBlock.push(',"<', this.tagName, '"');
-
- for (var name in this.attrs)
- {
- if (name != "class")
- {
- var val = this.attrs[name];
- topBlock.push(', " ', name, '=\\""');
- addParts(val, ',', topBlock, info, true);
- topBlock.push(', "\\""');
- }
- }
-
- if (this.listeners)
- {
- for (var i = 0; i < this.listeners.length; i += 2)
- readPartNames(this.listeners[i+1], topOuts);
- }
-
- if (this.props)
- {
- for (var name in this.props)
- readPartNames(this.props[name], topOuts);
- }
-
- if ( this.attrs.hasOwnProperty("class") || this.classes)
- {
- topBlock.push(', " class=\\""');
- if (this.attrs.hasOwnProperty("class"))
- addParts(this.attrs["class"], ',', topBlock, info, true);
- topBlock.push(', " "');
- for (var name in this.classes)
- {
- topBlock.push(', (');
- addParts(this.classes[name], '', topBlock, info);
- topBlock.push(' ? "', name, '" + " " : "")');
- }
- topBlock.push(', "\\""');
- }
- topBlock.push(',">"');
-
- this.generateChildMarkup(topBlock, topOuts, blocks, info);
- topBlock.push(',"</', this.tagName, '>"');
- },
-
- generateChildMarkup: function(topBlock, topOuts, blocks, info)
- {
- for (var i = 0; i < this.children.length; ++i)
- {
- var child = this.children[i];
- if (isTag(child))
- child.tag.generateMarkup(topBlock, topOuts, blocks, info);
- else
- addParts(child, ',', topBlock, info, true);
- }
- },
-
- addCode: function(topBlock, topOuts, blocks)
- {
- if (topBlock.length)
- blocks.push('__code__.push(""', topBlock.join(""), ');');
- if (topOuts.length)
- blocks.push('__out__.push(', topOuts.join(","), ');');
- topBlock.splice(0, topBlock.length);
- topOuts.splice(0, topOuts.length);
- },
-
- addLocals: function(blocks)
- {
- var varNames = [];
- this.getVarNames(varNames);
-
- var map = {};
- for (var i = 0; i < varNames.length; ++i)
- {
- var name = varNames[i];
- if ( map.hasOwnProperty(name) )
- continue;
-
- map[name] = 1;
- var names = name.split(".");
- blocks.push('var ', names[0] + ' = ' + '__in__.' + names[0] + ';');
- }
- },
-
- compileDOM: function()
- {
- var path = [];
- var blocks = [];
- this.domArgs = [];
- path.embedIndex = 0;
- path.loopIndex = 0;
- path.staticIndex = 0;
- path.renderIndex = 0;
- var nodeCount = this.generateDOM(path, blocks, this.domArgs);
-
- var fnBlock = ['r=(function (root, context, o'];
-
- for (var i = 0; i < path.staticIndex; ++i)
- fnBlock.push(', ', 's'+i);
-
- for (var i = 0; i < path.renderIndex; ++i)
- fnBlock.push(', ', 'd'+i);
-
- fnBlock.push(') {');
- for (var i = 0; i < path.loopIndex; ++i)
- fnBlock.push('var l', i, ' = 0;');
- for (var i = 0; i < path.embedIndex; ++i)
- fnBlock.push('var e', i, ' = 0;');
-
- if (this.subject)
- fnBlock.push('with (this) {');
- if (this.context)
- fnBlock.push('with (context) {');
-
- fnBlock.push(blocks.join(""));
-
- if (this.subject)
- fnBlock.push('}');
- if (this.context)
- fnBlock.push('}');
-
- fnBlock.push('return ', nodeCount, ';');
- fnBlock.push('})');
-
- function __bind__(object, fn)
- {
- return function(event) { return fn.apply(object, [event]); };
- }
-
- function __link__(node, tag, args)
- {
- if (!tag || !tag.tag)
- return;
-
- tag.tag.compile();
-
- var domArgs = [node, tag.tag.context, 0];
- domArgs.push.apply(domArgs, tag.tag.domArgs);
- domArgs.push.apply(domArgs, args);
- //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate__link__ domArgs:", domArgs);
- return tag.tag.renderDOM.apply(tag.tag.subject, domArgs);
- }
-
- var self = this;
- function __loop__(iter, fn)
- {
- var nodeCount = 0;
- for (var i = 0; i < iter.length; ++i)
- {
- iter[i][0] = i;
- iter[i][1] = nodeCount;
- nodeCount += fn.apply(this, iter[i]);
- //if (FBTrace.DBG_DOM) FBTrace.sysout("nodeCount", nodeCount);
- }
- return nodeCount;
- }
-
- function __path__(parent, offset)
- {
- //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate __path__ offset: "+ offset+"\n");
- var root = parent;
-
- for (var i = 2; i < arguments.length; ++i)
- {
- var index = arguments[i];
- if (i == 3)
- index += offset;
-
- if (index == -1)
- parent = parent.parentNode;
- else
- parent = parent.childNodes[index];
- }
-
- //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate: "+arguments[2]+", root: "+ root+", parent: "+ parent+"\n");
- return parent;
- }
-
- var js = fnBlock.join("");
- //if (FBTrace.DBG_DOM) FBTrace.sysout(js.replace(/(\;|\{)/g, "$1\n"));
- var r = null;
- eval(js);
- this.renderDOM = r;
- },
-
- generateDOM: function(path, blocks, args)
- {
- if (this.listeners || this.props)
- this.generateNodePath(path, blocks);
-
- if (this.listeners)
- {
- for (var i = 0; i < this.listeners.length; i += 2)
- {
- var val = this.listeners[i+1];
- var arg = generateArg(val, path, args);
- //blocks.push('node.addEventListener("', this.listeners[i], '", __bind__(this, ', arg, '), false);');
- blocks.push('addEvent(node, "', this.listeners[i], '", __bind__(this, ', arg, '), false);');
- }
- }
-
- if (this.props)
- {
- for (var name in this.props)
- {
- var val = this.props[name];
- var arg = generateArg(val, path, args);
- blocks.push('node.', name, ' = ', arg, ';');
- }
- }
-
- this.generateChildDOM(path, blocks, args);
- return 1;
- },
-
- generateNodePath: function(path, blocks)
- {
- blocks.push("var node = __path__(root, o");
- for (var i = 0; i < path.length; ++i)
- blocks.push(",", path[i]);
- blocks.push(");");
- },
-
- generateChildDOM: function(path, blocks, args)
- {
- path.push(0);
- for (var i = 0; i < this.children.length; ++i)
- {
- var child = this.children[i];
- if (isTag(child))
- path[path.length-1] += '+' + child.tag.generateDOM(path, blocks, args);
- else
- path[path.length-1] += '+1';
- }
- path.pop();
- }
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-FBL.DomplateEmbed.prototype = copyObject(FBL.DomplateTag.prototype,
-/** @lends FBL.DomplateEmbed.prototype */
-{
- merge: function(args, oldTag)
- {
- this.value = oldTag ? oldTag.value : parseValue(args[0]);
- this.attrs = oldTag ? oldTag.attrs : {};
- this.vars = oldTag ? copyArray(oldTag.vars) : [];
-
- var attrs = args[1];
- for (var name in attrs)
- {
- var val = parseValue(attrs[name]);
- this.attrs[name] = val;
- readPartNames(val, this.vars);
- }
-
- return creator(this, DomplateEmbed);
- },
-
- getVarNames: function(names)
- {
- if (this.value instanceof Parts)
- names.push(this.value.parts[0].name);
-
- if (this.vars)
- names.push.apply(names, this.vars);
- },
-
- generateMarkup: function(topBlock, topOuts, blocks, info)
- {
- this.addCode(topBlock, topOuts, blocks);
-
- blocks.push('__link__(');
- addParts(this.value, '', blocks, info);
- blocks.push(', __code__, __out__, {');
-
- var lastName = null;
- for (var name in this.attrs)
- {
- if (lastName)
- blocks.push(',');
- lastName = name;
-
- var val = this.attrs[name];
- blocks.push('"', name, '":');
- addParts(val, '', blocks, info);
- }
-
- blocks.push('});');
- //this.generateChildMarkup(topBlock, topOuts, blocks, info);
- },
-
- generateDOM: function(path, blocks, args)
- {
- var embedName = 'e'+path.embedIndex++;
-
- this.generateNodePath(path, blocks);
-
- var valueName = 'd' + path.renderIndex++;
- var argsName = 'd' + path.renderIndex++;
- blocks.push(embedName + ' = __link__(node, ', valueName, ', ', argsName, ');');
-
- return embedName;
- }
-});
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-FBL.DomplateLoop.prototype = copyObject(FBL.DomplateTag.prototype,
-/** @lends FBL.DomplateLoop.prototype */
-{
- merge: function(args, oldTag)
- {
- this.varName = oldTag ? oldTag.varName : args[0];
- this.iter = oldTag ? oldTag.iter : parseValue(args[1]);
- this.vars = [];
-
- this.children = oldTag ? copyArray(oldTag.children) : [];
-
- var offset = Math.min(args.length, 2);
- parseChildren(args, offset, this.vars, this.children);
-
- return creator(this, DomplateLoop);
- },
-
- getVarNames: function(names)
- {
- if (this.iter instanceof Parts)
- names.push(this.iter.parts[0].name);
-
- DomplateTag.prototype.getVarNames.apply(this, [names]);
- },
-
- generateMarkup: function(topBlock, topOuts, blocks, info)
- {
- this.addCode(topBlock, topOuts, blocks);
-
- var iterName;
- if (this.iter instanceof Parts)
- {
- var part = this.iter.parts[0];
- iterName = part.name;
-
- if (part.format)
- {
- for (var i = 0; i < part.format.length; ++i)
- iterName = part.format[i] + "(" + iterName + ")";
- }
- }
- else
- iterName = this.iter;
-
- blocks.push('__loop__.apply(this, [', iterName, ', __out__, function(', this.varName, ', __out__) {');
- this.generateChildMarkup(topBlock, topOuts, blocks, info);
- this.addCode(topBlock, topOuts, blocks);
- blocks.push('}]);');
- },
-
- generateDOM: function(path, blocks, args)
- {
- var iterName = 'd'+path.renderIndex++;
- var counterName = 'i'+path.loopIndex;
- var loopName = 'l'+path.loopIndex++;
-
- if (!path.length)
- path.push(-1, 0);
-
- var preIndex = path.renderIndex;
- path.renderIndex = 0;
-
- var nodeCount = 0;
-
- var subBlocks = [];
- var basePath = path[path.length-1];
- for (var i = 0; i < this.children.length; ++i)
- {
- path[path.length-1] = basePath+'+'+loopName+'+'+nodeCount;
-
- var child = this.children[i];
- if (isTag(child))
- nodeCount += '+' + child.tag.generateDOM(path, subBlocks, args);
- else
- nodeCount += '+1';
- }
-
- path[path.length-1] = basePath+'+'+loopName;
-
- blocks.push(loopName,' = __loop__.apply(this, [', iterName, ', function(', counterName,',',loopName);
- for (var i = 0; i < path.renderIndex; ++i)
- blocks.push(',d'+i);
- blocks.push(') {');
- blocks.push(subBlocks.join(""));
- blocks.push('return ', nodeCount, ';');
- blocks.push('}]);');
-
- path.renderIndex = preIndex;
-
- return loopName;
- }
-});
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-/** @class */
-function Variable(name, format)
-{
- this.name = name;
- this.format = format;
-}
-
-/** @class */
-function Parts(parts)
-{
- this.parts = parts;
-}
-
-// ************************************************************************************************
-
-function parseParts(str)
-{
- var re = /\$([_A-Za-z][_A-Za-z0-9.|]*)/g;
- var index = 0;
- var parts = [];
-
- var m;
- while (m = re.exec(str))
- {
- var pre = str.substr(index, (re.lastIndex-m[0].length)-index);
- if (pre)
- parts.push(pre);
-
- var expr = m[1].split("|");
- parts.push(new Variable(expr[0], expr.slice(1)));
- index = re.lastIndex;
- }
-
- if (!index)
- return str;
-
- var post = str.substr(index);
- if (post)
- parts.push(post);
-
- return new Parts(parts);
-}
-
-function parseValue(val)
-{
- return typeof(val) == 'string' ? parseParts(val) : val;
-}
-
-function parseChildren(args, offset, vars, children)
-{
- for (var i = offset; i < args.length; ++i)
- {
- var val = parseValue(args[i]);
- children.push(val);
- readPartNames(val, vars);
- }
-}
-
-function readPartNames(val, vars)
-{
- if (val instanceof Parts)
- {
- for (var i = 0; i < val.parts.length; ++i)
- {
- var part = val.parts[i];
- if (part instanceof Variable)
- vars.push(part.name);
- }
- }
-}
-
-function generateArg(val, path, args)
-{
- if (val instanceof Parts)
- {
- var vals = [];
- for (var i = 0; i < val.parts.length; ++i)
- {
- var part = val.parts[i];
- if (part instanceof Variable)
- {
- var varName = 'd'+path.renderIndex++;
- if (part.format)
- {
- for (var j = 0; j < part.format.length; ++j)
- varName = part.format[j] + '(' + varName + ')';
- }
-
- vals.push(varName);
- }
- else
- vals.push('"'+part.replace(/"/g, '\\"')+'"');
- }
-
- return vals.join('+');
- }
- else
- {
- args.push(val);
- return 's' + path.staticIndex++;
- }
-}
-
-function addParts(val, delim, block, info, escapeIt)
-{
- var vals = [];
- if (val instanceof Parts)
- {
- for (var i = 0; i < val.parts.length; ++i)
- {
- var part = val.parts[i];
- if (part instanceof Variable)
- {
- var partName = part.name;
- if (part.format)
- {
- for (var j = 0; j < part.format.length; ++j)
- partName = part.format[j] + "(" + partName + ")";
- }
-
- if (escapeIt)
- vals.push("__escape__(" + partName + ")");
- else
- vals.push(partName);
- }
- else
- vals.push('"'+ part + '"');
- }
- }
- else if (isTag(val))
- {
- info.args.push(val);
- vals.push('s'+info.argIndex++);
- }
- else
- vals.push('"'+ val + '"');
-
- var parts = vals.join(delim);
- if (parts)
- block.push(delim, parts);
-}
-
-function isTag(obj)
-{
- return (typeof(obj) == "function" || obj instanceof Function) && !!obj.tag;
-}
-
-function creator(tag, cons)
-{
- var fn = new Function(
- "var tag = arguments.callee.tag;" +
- "var cons = arguments.callee.cons;" +
- "var newTag = new cons();" +
- "return newTag.merge(arguments, tag);");
-
- fn.tag = tag;
- fn.cons = cons;
- extend(fn, Renderer);
-
- return fn;
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-function copyArray(oldArray)
-{
- var ary = [];
- if (oldArray)
- for (var i = 0; i < oldArray.length; ++i)
- ary.push(oldArray[i]);
- return ary;
-}
-
-function copyObject(l, r)
-{
- var m = {};
- extend(m, l);
- extend(m, r);
- return m;
-}
-
-function extend(l, r)
-{
- for (var n in r)
- l[n] = r[n];
-}
-
-function addEvent(object, name, handler)
-{
- if (document.all)
- object.attachEvent("on"+name, handler);
- else
- object.addEventListener(name, handler, false);
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-/** @class */
-function ArrayIterator(array)
-{
- var index = -1;
-
- this.next = function()
- {
- if (++index >= array.length)
- throw StopIteration;
-
- return array[index];
- };
-}
-
-/** @class */
-function StopIteration() {}
-
-FBL.$break = function()
-{
- throw StopIteration;
-};
-
-// ************************************************************************************************
-
-/** @namespace */
-var Renderer =
-{
- renderHTML: function(args, outputs, self)
- {
- var code = [];
- var markupArgs = [code, this.tag.context, args, outputs];
- markupArgs.push.apply(markupArgs, this.tag.markupArgs);
- this.tag.renderMarkup.apply(self ? self : this.tag.subject, markupArgs);
- return code.join("");
- },
-
- insertRows: function(args, before, self)
- {
- this.tag.compile();
-
- var outputs = [];
- var html = this.renderHTML(args, outputs, self);
-
- var doc = before.ownerDocument;
- var div = doc.createElement("div");
- div.innerHTML = "<table><tbody>"+html+"</tbody></table>";
-
- var tbody = div.firstChild.firstChild;
- var parent = before.tagName == "TR" ? before.parentNode : before;
- var after = before.tagName == "TR" ? before.nextSibling : null;
-
- var firstRow = tbody.firstChild, lastRow;
- while (tbody.firstChild)
- {
- lastRow = tbody.firstChild;
- if (after)
- parent.insertBefore(lastRow, after);
- else
- parent.appendChild(lastRow);
- }
-
- var offset = 0;
- if (before.tagName == "TR")
- {
- var node = firstRow.parentNode.firstChild;
- for (; node && node != firstRow; node = node.nextSibling)
- ++offset;
- }
-
- var domArgs = [firstRow, this.tag.context, offset];
- domArgs.push.apply(domArgs, this.tag.domArgs);
- domArgs.push.apply(domArgs, outputs);
-
- this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
- return [firstRow, lastRow];
- },
-
- insertBefore: function(args, before, self)
- {
- return this.insertNode(args, before.ownerDocument, before, false, self);
- },
-
- insertAfter: function(args, after, self)
- {
- return this.insertNode(args, after.ownerDocument, after, true, self);
- },
-
- insertNode: function(args, doc, element, isAfter, self)
- {
- if (!args)
- args = {};
-
- this.tag.compile();
-
- var outputs = [];
- var html = this.renderHTML(args, outputs, self);
-
- //if (FBTrace.DBG_DOM)
- // FBTrace.sysout("domplate.insertNode html: "+html+"\n");
-
- var doc = element.ownerDocument;
- if (!womb || womb.ownerDocument != doc)
- womb = doc.createElement("div");
-
- womb.innerHTML = html;
-
- var root = womb.firstChild;
- if (isAfter)
- {
- while (womb.firstChild)
- if (element.nextSibling)
- element.parentNode.insertBefore(womb.firstChild, element.nextSibling);
- else
- element.parentNode.appendChild(womb.firstChild);
- }
- else
- {
- while (womb.lastChild)
- element.parentNode.insertBefore(womb.lastChild, element);
- }
-
- var domArgs = [root, this.tag.context, 0];
- domArgs.push.apply(domArgs, this.tag.domArgs);
- domArgs.push.apply(domArgs, outputs);
-
- //if (FBTrace.DBG_DOM)
- // FBTrace.sysout("domplate.insertNode domArgs:", domArgs);
- this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
-
- return root;
- },
- /**/
-
- /*
- insertAfter: function(args, before, self)
- {
- this.tag.compile();
-
- var outputs = [];
- var html = this.renderHTML(args, outputs, self);
-
- var doc = before.ownerDocument;
- if (!womb || womb.ownerDocument != doc)
- womb = doc.createElement("div");
-
- womb.innerHTML = html;
-
- var root = womb.firstChild;
- while (womb.firstChild)
- if (before.nextSibling)
- before.parentNode.insertBefore(womb.firstChild, before.nextSibling);
- else
- before.parentNode.appendChild(womb.firstChild);
-
- var domArgs = [root, this.tag.context, 0];
- domArgs.push.apply(domArgs, this.tag.domArgs);
- domArgs.push.apply(domArgs, outputs);
-
- this.tag.renderDOM.apply(self ? self : (this.tag.subject ? this.tag.subject : null),
- domArgs);
-
- return root;
- },
- /**/
-
- replace: function(args, parent, self)
- {
- this.tag.compile();
-
- var outputs = [];
- var html = this.renderHTML(args, outputs, self);
-
- var root;
- if (parent.nodeType == 1)
- {
- parent.innerHTML = html;
- root = parent.firstChild;
- }
- else
- {
- if (!parent || parent.nodeType != 9)
- parent = document;
-
- if (!womb || womb.ownerDocument != parent)
- womb = parent.createElement("div");
- womb.innerHTML = html;
-
- root = womb.firstChild;
- //womb.removeChild(root);
- }
-
- var domArgs = [root, this.tag.context, 0];
- domArgs.push.apply(domArgs, this.tag.domArgs);
- domArgs.push.apply(domArgs, outputs);
- this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
-
- return root;
- },
-
- append: function(args, parent, self)
- {
- this.tag.compile();
-
- var outputs = [];
- var html = this.renderHTML(args, outputs, self);
- //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate.append html: "+html+"\n");
-
- if (!womb || womb.ownerDocument != parent.ownerDocument)
- womb = parent.ownerDocument.createElement("div");
- womb.innerHTML = html;
-
- // TODO: xxxpedro domplate port to Firebug
- var root = womb.firstChild;
- while (womb.firstChild)
- parent.appendChild(womb.firstChild);
-
- // clearing element reference to avoid reference error in IE8 when switching contexts
- womb = null;
-
- var domArgs = [root, this.tag.context, 0];
- domArgs.push.apply(domArgs, this.tag.domArgs);
- domArgs.push.apply(domArgs, outputs);
-
- //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate append domArgs:", domArgs);
- this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
-
- return root;
- }
-};
-
-// ************************************************************************************************
-
-function defineTags()
-{
- for (var i = 0; i < arguments.length; ++i)
- {
- var tagName = arguments[i];
- var fn = new Function("var newTag = new arguments.callee.DomplateTag('"+tagName+"'); return newTag.merge(arguments);");
- fn.DomplateTag = DomplateTag;
-
- var fnName = tagName.toUpperCase();
- FBL[fnName] = fn;
- }
-}
-
-defineTags(
- "a", "button", "br", "canvas", "code", "col", "colgroup", "div", "fieldset", "form", "h1", "h2", "h3", "hr",
- "img", "input", "label", "legend", "li", "ol", "optgroup", "option", "p", "pre", "select",
- "span", "strong", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "tr", "tt", "ul", "iframe"
-);
-
-})();
-
-
-/* See license.txt for terms of usage */
-
-var FirebugReps = FBL.ns(function() { with (FBL) {
-
-
-// ************************************************************************************************
-// Common Tags
-
-var OBJECTBOX = this.OBJECTBOX =
- SPAN({"class": "objectBox objectBox-$className"});
-
-var OBJECTBLOCK = this.OBJECTBLOCK =
- DIV({"class": "objectBox objectBox-$className"});
-
-var OBJECTLINK = this.OBJECTLINK = isIE6 ? // IE6 object link representation
- A({
- "class": "objectLink objectLink-$className a11yFocus",
- href: "javascript:void(0)",
- // workaround to show XPath (a better approach would use the tooltip on mouseover,
- // so the XPath information would be calculated dynamically, but we need to create
- // a tooltip class/wrapper around Menu or InfoTip)
- title: "$object|FBL.getElementXPath",
- _repObject: "$object"
- })
- : // Other browsers
- A({
- "class": "objectLink objectLink-$className a11yFocus",
- // workaround to show XPath (a better approach would use the tooltip on mouseover,
- // so the XPath information would be calculated dynamically, but we need to create
- // a tooltip class/wrapper around Menu or InfoTip)
- title: "$object|FBL.getElementXPath",
- _repObject: "$object"
- });
-
-
-// ************************************************************************************************
-
-this.Undefined = domplate(Firebug.Rep,
-{
- tag: OBJECTBOX("undefined"),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "undefined",
-
- supportsObject: function(object, type)
- {
- return type == "undefined";
- }
-});
-
-// ************************************************************************************************
-
-this.Null = domplate(Firebug.Rep,
-{
- tag: OBJECTBOX("null"),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "null",
-
- supportsObject: function(object, type)
- {
- return object == null;
- }
-});
-
-// ************************************************************************************************
-
-this.Nada = domplate(Firebug.Rep,
-{
- tag: SPAN(""),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "nada"
-});
-
-// ************************************************************************************************
-
-this.Number = domplate(Firebug.Rep,
-{
- tag: OBJECTBOX("$object"),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "number",
-
- supportsObject: function(object, type)
- {
- return type == "boolean" || type == "number";
- }
-});
-
-// ************************************************************************************************
-
-this.String = domplate(Firebug.Rep,
-{
- tag: OBJECTBOX("&quot;$object&quot;"),
-
- shortTag: OBJECTBOX("&quot;$object|cropString&quot;"),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "string",
-
- supportsObject: function(object, type)
- {
- return type == "string";
- }
-});
-
-// ************************************************************************************************
-
-this.Text = domplate(Firebug.Rep,
-{
- tag: OBJECTBOX("$object"),
-
- shortTag: OBJECTBOX("$object|cropString"),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "text"
-});
-
-// ************************************************************************************************
-
-this.Caption = domplate(Firebug.Rep,
-{
- tag: SPAN({"class": "caption"}, "$object")
-});
-
-// ************************************************************************************************
-
-this.Warning = domplate(Firebug.Rep,
-{
- tag: DIV({"class": "warning focusRow", role : 'listitem'}, "$object|STR")
-});
-
-// ************************************************************************************************
-
-this.Func = domplate(Firebug.Rep,
-{
- tag:
- OBJECTLINK("$object|summarizeFunction"),
-
- summarizeFunction: function(fn)
- {
- var fnRegex = /function ([^(]+\([^)]*\)) \{/;
- var fnText = safeToString(fn);
-
- var m = fnRegex.exec(fnText);
- return m ? m[1] : "function()";
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- copySource: function(fn)
- {
- copyToClipboard(safeToString(fn));
- },
-
- monitor: function(fn, script, monitored)
- {
- if (monitored)
- Firebug.Debugger.unmonitorScript(fn, script, "monitor");
- else
- Firebug.Debugger.monitorScript(fn, script, "monitor");
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "function",
-
- supportsObject: function(object, type)
- {
- return isFunction(object);
- },
-
- inspectObject: function(fn, context)
- {
- var sourceLink = findSourceForFunction(fn, context);
- if (sourceLink)
- Firebug.chrome.select(sourceLink);
- if (FBTrace.DBG_FUNCTION_NAME)
- FBTrace.sysout("reps.function.inspectObject selected sourceLink is ", sourceLink);
- },
-
- getTooltip: function(fn, context)
- {
- var script = findScriptForFunctionInContext(context, fn);
- if (script)
- return $STRF("Line", [normalizeURL(script.fileName), script.baseLineNumber]);
- else
- if (fn.toString)
- return fn.toString();
- },
-
- getTitle: function(fn, context)
- {
- var name = fn.name ? fn.name : "function";
- return name + "()";
- },
-
- getContextMenuItems: function(fn, target, context, script)
- {
- if (!script)
- script = findScriptForFunctionInContext(context, fn);
- if (!script)
- return;
-
- var scriptInfo = getSourceFileAndLineByScript(context, script);
- var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false;
-
- var name = script ? getFunctionName(script, context) : fn.name;
- return [
- {label: "CopySource", command: bindFixed(this.copySource, this, fn) },
- "-",
- {label: $STRF("ShowCallsInConsole", [name]), nol10n: true,
- type: "checkbox", checked: monitored,
- command: bindFixed(this.monitor, this, fn, script, monitored) }
- ];
- }
-});
-
-// ************************************************************************************************
-/*
-this.jsdScript = domplate(Firebug.Rep,
-{
- copySource: function(script)
- {
- var fn = script.functionObject.getWrappedValue();
- return FirebugReps.Func.copySource(fn);
- },
-
- monitor: function(fn, script, monitored)
- {
- fn = script.functionObject.getWrappedValue();
- return FirebugReps.Func.monitor(fn, script, monitored);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "jsdScript",
- inspectable: false,
-
- supportsObject: function(object, type)
- {
- return object instanceof jsdIScript;
- },
-
- inspectObject: function(script, context)
- {
- var sourceLink = getSourceLinkForScript(script, context);
- if (sourceLink)
- Firebug.chrome.select(sourceLink);
- },
-
- getRealObject: function(script, context)
- {
- return script;
- },
-
- getTooltip: function(script)
- {
- return $STRF("jsdIScript", [script.tag]);
- },
-
- getTitle: function(script, context)
- {
- var fn = script.functionObject.getWrappedValue();
- return FirebugReps.Func.getTitle(fn, context);
- },
-
- getContextMenuItems: function(script, target, context)
- {
- var fn = script.functionObject.getWrappedValue();
-
- var scriptInfo = getSourceFileAndLineByScript(context, script);
- var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false;
-
- var name = getFunctionName(script, context);
-
- return [
- {label: "CopySource", command: bindFixed(this.copySource, this, script) },
- "-",
- {label: $STRF("ShowCallsInConsole", [name]), nol10n: true,
- type: "checkbox", checked: monitored,
- command: bindFixed(this.monitor, this, fn, script, monitored) }
- ];
- }
-});
-/**/
-//************************************************************************************************
-
-this.Obj = domplate(Firebug.Rep,
-{
- tag:
- OBJECTLINK(
- SPAN({"class": "objectTitle"}, "$object|getTitle "),
-
- SPAN({"class": "objectProps"},
- SPAN({"class": "objectLeftBrace", role: "presentation"}, "{"),
- FOR("prop", "$object|propIterator",
- SPAN({"class": "objectPropName", role: "presentation"}, "$prop.name"),
- SPAN({"class": "objectEqual", role: "presentation"}, "$prop.equal"),
- TAG("$prop.tag", {object: "$prop.object"}),
- SPAN({"class": "objectComma", role: "presentation"}, "$prop.delim")
- ),
- SPAN({"class": "objectRightBrace"}, "}")
- )
- ),
-
- propNumberTag:
- SPAN({"class": "objectProp-number"}, "$object"),
-
- propStringTag:
- SPAN({"class": "objectProp-string"}, "&quot;$object&quot;"),
-
- propObjectTag:
- SPAN({"class": "objectProp-object"}, "$object"),
-
- propIterator: function (object)
- {
- ///Firebug.ObjectShortIteratorMax;
- var maxLength = 55; // default max length for long representation
-
- if (!object)
- return [];
-
- var props = [];
- var length = 0;
-
- var numProperties = 0;
- var numPropertiesShown = 0;
- var maxLengthReached = false;
-
- var lib = this;
-
- var propRepsMap =
- {
- "boolean": this.propNumberTag,
- "number": this.propNumberTag,
- "string": this.propStringTag,
- "object": this.propObjectTag
- };
-
- try
- {
- var title = Firebug.Rep.getTitle(object);
- length += title.length;
-
- for (var name in object)
- {
- var value;
- try
- {
- value = object[name];
- }
- catch (exc)
- {
- continue;
- }
-
- var type = typeof(value);
- if (type == "boolean" ||
- type == "number" ||
- (type == "string" && value) ||
- (type == "object" && value && value.toString))
- {
- var tag = propRepsMap[type];
-
- var value = (type == "object") ?
- Firebug.getRep(value).getTitle(value) :
- value + "";
-
- length += name.length + value.length + 4;
-
- if (length <= maxLength)
- {
- props.push({
- tag: tag,
- name: name,
- object: value,
- equal: "=",
- delim: ", "
- });
-
- numPropertiesShown++;
- }
- else
- maxLengthReached = true;
-
- }
-
- numProperties++;
-
- if (maxLengthReached && numProperties > numPropertiesShown)
- break;
- }
-
- if (numProperties > numPropertiesShown)
- {
- props.push({
- object: "...", //xxxHonza localization
- tag: FirebugReps.Caption.tag,
- name: "",
- equal:"",
- delim:""
- });
- }
- else if (props.length > 0)
- {
- props[props.length-1].delim = '';
- }
- }
- catch (exc)
- {
- // Sometimes we get exceptions when trying to read from certain objects, like
- // StorageList, but don't let that gum up the works
- // XXXjjb also History.previous fails because object is a web-page object which does not have
- // permission to read the history
- }
- return props;
- },
-
- fb_1_6_propIterator: function (object, max)
- {
- max = max || 3;
- if (!object)
- return [];
-
- var props = [];
- var len = 0, count = 0;
-
- try
- {
- for (var name in object)
- {
- var value;
- try
- {
- value = object[name];
- }
- catch (exc)
- {
- continue;
- }
-
- var t = typeof(value);
- if (t == "boolean" || t == "number" || (t == "string" && value)
- || (t == "object" && value && value.toString))
- {
- var rep = Firebug.getRep(value);
- var tag = rep.shortTag || rep.tag;
- if (t == "object")
- {
- value = rep.getTitle(value);
- tag = rep.titleTag;
- }
- count++;
- if (count <= max)
- props.push({tag: tag, name: name, object: value, equal: "=", delim: ", "});
- else
- break;
- }
- }
- if (count > max)
- {
- props[Math.max(1,max-1)] = {
- object: "more...", //xxxHonza localization
- tag: FirebugReps.Caption.tag,
- name: "",
- equal:"",
- delim:""
- };
- }
- else if (props.length > 0)
- {
- props[props.length-1].delim = '';
- }
- }
- catch (exc)
- {
- // Sometimes we get exceptions when trying to read from certain objects, like
- // StorageList, but don't let that gum up the works
- // XXXjjb also History.previous fails because object is a web-page object which does not have
- // permission to read the history
- }
- return props;
- },
-
- /*
- propIterator: function (object)
- {
- if (!object)
- return [];
-
- var props = [];
- var len = 0;
-
- try
- {
- for (var name in object)
- {
- var val;
- try
- {
- val = object[name];
- }
- catch (exc)
- {
- continue;
- }
-
- var t = typeof val;
- if (t == "boolean" || t == "number" || (t == "string" && val)
- || (t == "object" && !isFunction(val) && val && val.toString))
- {
- var title = (t == "object")
- ? Firebug.getRep(val).getTitle(val)
- : val+"";
-
- len += name.length + title.length + 1;
- if (len < 50)
- props.push({name: name, value: title});
- else
- break;
- }
- }
- }
- catch (exc)
- {
- // Sometimes we get exceptions when trying to read from certain objects, like
- // StorageList, but don't let that gum up the works
- // XXXjjb also History.previous fails because object is a web-page object which does not have
- // permission to read the history
- }
-
- return props;
- },
- /**/
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "object",
-
- supportsObject: function(object, type)
- {
- return true;
- }
-});
-
-
-// ************************************************************************************************
-
-this.Arr = domplate(Firebug.Rep,
-{
- tag:
- OBJECTBOX({_repObject: "$object"},
- SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["),
- FOR("item", "$object|arrayIterator",
- TAG("$item.tag", {object: "$item.object"}),
- SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim")
- ),
- SPAN({"class": "arrayRightBracket", role : "presentation"}, "]")
- ),
-
- shortTag:
- OBJECTBOX({_repObject: "$object"},
- SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["),
- FOR("item", "$object|shortArrayIterator",
- TAG("$item.tag", {object: "$item.object"}),
- SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim")
- ),
- // TODO: xxxpedro - confirm this on Firebug
- //FOR("prop", "$object|shortPropIterator",
- // " $prop.name=",
- // SPAN({"class": "objectPropValue"}, "$prop.value|cropString")
- //),
- SPAN({"class": "arrayRightBracket"}, "]")
- ),
-
- arrayIterator: function(array)
- {
- var items = [];
- for (var i = 0; i < array.length; ++i)
- {
- var value = array[i];
- var rep = Firebug.getRep(value);
- var tag = rep.shortTag ? rep.shortTag : rep.tag;
- var delim = (i == array.length-1 ? "" : ", ");
-
- items.push({object: value, tag: tag, delim: delim});
- }
-
- return items;
- },
-
- shortArrayIterator: function(array)
- {
- var items = [];
- for (var i = 0; i < array.length && i < 3; ++i)
- {
- var value = array[i];
- var rep = Firebug.getRep(value);
- var tag = rep.shortTag ? rep.shortTag : rep.tag;
- var delim = (i == array.length-1 ? "" : ", ");
-
- items.push({object: value, tag: tag, delim: delim});
- }
-
- if (array.length > 3)
- items.push({object: (array.length-3) + " more...", tag: FirebugReps.Caption.tag, delim: ""});
-
- return items;
- },
-
- shortPropIterator: this.Obj.propIterator,
-
- getItemIndex: function(child)
- {
- var arrayIndex = 0;
- for (child = child.previousSibling; child; child = child.previousSibling)
- {
- if (child.repObject)
- ++arrayIndex;
- }
- return arrayIndex;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "array",
-
- supportsObject: function(object)
- {
- return this.isArray(object);
- },
-
- // http://code.google.com/p/fbug/issues/detail?id=874
- // BEGIN Yahoo BSD Source (modified here) YAHOO.lang.isArray, YUI 2.2.2 June 2007
- isArray: function(obj) {
- try {
- if (!obj)
- return false;
- else if (isIE && !isFunction(obj) && typeof obj == "object" && isFinite(obj.length) && obj.nodeType != 8)
- return true;
- else if (isFinite(obj.length) && isFunction(obj.splice))
- return true;
- else if (isFinite(obj.length) && isFunction(obj.callee)) // arguments
- return true;
- else if (instanceOf(obj, "HTMLCollection"))
- return true;
- else if (instanceOf(obj, "NodeList"))
- return true;
- else
- return false;
- }
- catch(exc)
- {
- if (FBTrace.DBG_ERRORS)
- {
- FBTrace.sysout("isArray FAILS:", exc); /* Something weird: without the try/catch, OOM, with no exception?? */
- FBTrace.sysout("isArray Fails on obj", obj);
- }
- }
-
- return false;
- },
- // END Yahoo BSD SOURCE See license below.
-
- getTitle: function(object, context)
- {
- return "[" + object.length + "]";
- }
-});
-
-// ************************************************************************************************
-
-this.Property = domplate(Firebug.Rep,
-{
- supportsObject: function(object)
- {
- return object instanceof Property;
- },
-
- getRealObject: function(prop, context)
- {
- return prop.object[prop.name];
- },
-
- getTitle: function(prop, context)
- {
- return prop.name;
- }
-});
-
-// ************************************************************************************************
-
-this.NetFile = domplate(this.Obj,
-{
- supportsObject: function(object)
- {
- return object instanceof Firebug.NetFile;
- },
-
- browseObject: function(file, context)
- {
- openNewTab(file.href);
- return true;
- },
-
- getRealObject: function(file, context)
- {
- return null;
- }
-});
-
-// ************************************************************************************************
-
-this.Except = domplate(Firebug.Rep,
-{
- tag:
- OBJECTBOX({_repObject: "$object"}, "$object.message"),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "exception",
-
- supportsObject: function(object)
- {
- return object instanceof ErrorCopy;
- }
-});
-
-
-// ************************************************************************************************
-
-this.Element = domplate(Firebug.Rep,
-{
- tag:
- OBJECTLINK(
- "&lt;",
- SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"),
- FOR("attr", "$object|attrIterator",
- "&nbsp;$attr.nodeName=&quot;", SPAN({"class": "nodeValue"}, "$attr.nodeValue"), "&quot;"
- ),
- "&gt;"
- ),
-
- shortTag:
- OBJECTLINK(
- SPAN({"class": "$object|getVisible"},
- SPAN({"class": "selectorTag"}, "$object|getSelectorTag"),
- SPAN({"class": "selectorId"}, "$object|getSelectorId"),
- SPAN({"class": "selectorClass"}, "$object|getSelectorClass"),
- SPAN({"class": "selectorValue"}, "$object|getValue")
- )
- ),
-
- getVisible: function(elt)
- {
- return isVisible(elt) ? "" : "selectorHidden";
- },
-
- getSelectorTag: function(elt)
- {
- return elt.nodeName.toLowerCase();
- },
-
- getSelectorId: function(elt)
- {
- return elt.id ? "#" + elt.id : "";
- },
-
- getSelectorClass: function(elt)
- {
- return elt.className ? "." + elt.className.split(" ")[0] : "";
- },
-
- getValue: function(elt)
- {
- // TODO: xxxpedro
- return "";
- var value;
- if (elt instanceof HTMLImageElement)
- value = getFileName(elt.src);
- else if (elt instanceof HTMLAnchorElement)
- value = getFileName(elt.href);
- else if (elt instanceof HTMLInputElement)
- value = elt.value;
- else if (elt instanceof HTMLFormElement)
- value = getFileName(elt.action);
- else if (elt instanceof HTMLScriptElement)
- value = getFileName(elt.src);
-
- return value ? " " + cropString(value, 20) : "";
- },
-
- attrIterator: function(elt)
- {
- var attrs = [];
- var idAttr, classAttr;
- if (elt.attributes)
- {
- for (var i = 0; i < elt.attributes.length; ++i)
- {
- var attr = elt.attributes[i];
-
- // we must check if the attribute is specified otherwise IE will show them
- if (!attr.specified || attr.nodeName && attr.nodeName.indexOf("firebug-") != -1)
- continue;
- else if (attr.nodeName == "id")
- idAttr = attr;
- else if (attr.nodeName == "class")
- classAttr = attr;
- else if (attr.nodeName == "style")
- attrs.push({
- nodeName: attr.nodeName,
- nodeValue: attr.nodeValue ||
- // IE won't recognize the attr.nodeValue of <style> nodes ...
- // and will return CSS property names in upper case, so we need to convert them
- elt.style.cssText.replace(/([^\s]+)\s*:/g,
- function(m,g){return g.toLowerCase()+":"})
- });
- else
- attrs.push(attr);
- }
- }
- if (classAttr)
- attrs.splice(0, 0, classAttr);
- if (idAttr)
- attrs.splice(0, 0, idAttr);
-
- return attrs;
- },
-
- shortAttrIterator: function(elt)
- {
- var attrs = [];
- if (elt.attributes)
- {
- for (var i = 0; i < elt.attributes.length; ++i)
- {
- var attr = elt.attributes[i];
- if (attr.nodeName == "id" || attr.nodeName == "class")
- attrs.push(attr);
- }
- }
-
- return attrs;
- },
-
- getHidden: function(elt)
- {
- return isVisible(elt) ? "" : "nodeHidden";
- },
-
- getXPath: function(elt)
- {
- return getElementTreeXPath(elt);
- },
-
- // TODO: xxxpedro remove this?
- getNodeText: function(element)
- {
- var text = element.textContent;
- if (Firebug.showFullTextNodes)
- return text;
- else
- return cropString(text, 50);
- },
- /**/
-
- getNodeTextGroups: function(element)
- {
- var text = element.textContent;
- if (!Firebug.showFullTextNodes)
- {
- text=cropString(text,50);
- }
-
- var escapeGroups=[];
-
- if (Firebug.showTextNodesWithWhitespace)
- escapeGroups.push({
- 'group': 'whitespace',
- 'class': 'nodeWhiteSpace',
- 'extra': {
- '\t': '_Tab',
- '\n': '_Para',
- ' ' : '_Space'
- }
- });
- if (Firebug.showTextNodesWithEntities)
- escapeGroups.push({
- 'group':'text',
- 'class':'nodeTextEntity',
- 'extra':{}
- });
-
- if (escapeGroups.length)
- return escapeGroupsForEntities(text, escapeGroups);
- else
- return [{str:text,'class':'',extra:''}];
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- copyHTML: function(elt)
- {
- var html = getElementXML(elt);
- copyToClipboard(html);
- },
-
- copyInnerHTML: function(elt)
- {
- copyToClipboard(elt.innerHTML);
- },
-
- copyXPath: function(elt)
- {
- var xpath = getElementXPath(elt);
- copyToClipboard(xpath);
- },
-
- persistor: function(context, xpath)
- {
- var elts = xpath
- ? getElementsByXPath(context.window.document, xpath)
- : null;
-
- return elts && elts.length ? elts[0] : null;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "element",
-
- supportsObject: function(object)
- {
- //return object instanceof Element || object.nodeType == 1 && typeof object.nodeName == "string";
- return instanceOf(object, "Element");
- },
-
- browseObject: function(elt, context)
- {
- var tag = elt.nodeName.toLowerCase();
- if (tag == "script")
- openNewTab(elt.src);
- else if (tag == "link")
- openNewTab(elt.href);
- else if (tag == "a")
- openNewTab(elt.href);
- else if (tag == "img")
- openNewTab(elt.src);
-
- return true;
- },
-
- persistObject: function(elt, context)
- {
- var xpath = getElementXPath(elt);
-
- return bind(this.persistor, top, xpath);
- },
-
- getTitle: function(element, context)
- {
- return getElementCSSSelector(element);
- },
-
- getTooltip: function(elt)
- {
- return this.getXPath(elt);
- },
-
- getContextMenuItems: function(elt, target, context)
- {
- var monitored = areEventsMonitored(elt, null, context);
-
- return [
- {label: "CopyHTML", command: bindFixed(this.copyHTML, this, elt) },
- {label: "CopyInnerHTML", command: bindFixed(this.copyInnerHTML, this, elt) },
- {label: "CopyXPath", command: bindFixed(this.copyXPath, this, elt) },
- "-",
- {label: "ShowEventsInConsole", type: "checkbox", checked: monitored,
- command: bindFixed(toggleMonitorEvents, FBL, elt, null, monitored, context) },
- "-",
- {label: "ScrollIntoView", command: bindFixed(elt.scrollIntoView, elt) }
- ];
- }
-});
-
-// ************************************************************************************************
-
-this.TextNode = domplate(Firebug.Rep,
-{
- tag:
- OBJECTLINK(
- "&lt;",
- SPAN({"class": "nodeTag"}, "TextNode"),
- "&nbsp;textContent=&quot;", SPAN({"class": "nodeValue"}, "$object.textContent|cropString"), "&quot;",
- "&gt;"
- ),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "textNode",
-
- supportsObject: function(object)
- {
- return object instanceof Text;
- }
-});
-
-// ************************************************************************************************
-
-this.Document = domplate(Firebug.Rep,
-{
- tag:
- OBJECTLINK("Document ", SPAN({"class": "objectPropValue"}, "$object|getLocation")),
-
- getLocation: function(doc)
- {
- return doc.location ? getFileName(doc.location.href) : "";
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "object",
-
- supportsObject: function(object)
- {
- //return object instanceof Document || object instanceof XMLDocument;
- return instanceOf(object, "Document");
- },
-
- browseObject: function(doc, context)
- {
- openNewTab(doc.location.href);
- return true;
- },
-
- persistObject: function(doc, context)
- {
- return this.persistor;
- },
-
- persistor: function(context)
- {
- return context.window.document;
- },
-
- getTitle: function(win, context)
- {
- return "document";
- },
-
- getTooltip: function(doc)
- {
- return doc.location.href;
- }
-});
-
-// ************************************************************************************************
-
-this.StyleSheet = domplate(Firebug.Rep,
-{
- tag:
- OBJECTLINK("StyleSheet ", SPAN({"class": "objectPropValue"}, "$object|getLocation")),
-
- getLocation: function(styleSheet)
- {
- return getFileName(styleSheet.href);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- copyURL: function(styleSheet)
- {
- copyToClipboard(styleSheet.href);
- },
-
- openInTab: function(styleSheet)
- {
- openNewTab(styleSheet.href);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "object",
-
- supportsObject: function(object)
- {
- //return object instanceof CSSStyleSheet;
- return instanceOf(object, "CSSStyleSheet");
- },
-
- browseObject: function(styleSheet, context)
- {
- openNewTab(styleSheet.href);
- return true;
- },
-
- persistObject: function(styleSheet, context)
- {
- return bind(this.persistor, top, styleSheet.href);
- },
-
- getTooltip: function(styleSheet)
- {
- return styleSheet.href;
- },
-
- getContextMenuItems: function(styleSheet, target, context)
- {
- return [
- {label: "CopyLocation", command: bindFixed(this.copyURL, this, styleSheet) },
- "-",
- {label: "OpenInTab", command: bindFixed(this.openInTab, this, styleSheet) }
- ];
- },
-
- persistor: function(context, href)
- {
- return getStyleSheetByHref(href, context);
- }
-});
-
-// ************************************************************************************************
-
-this.Window = domplate(Firebug.Rep,
-{
- tag:
- OBJECTLINK("Window ", SPAN({"class": "objectPropValue"}, "$object|getLocation")),
-
- getLocation: function(win)
- {
- try
- {
- return (win && win.location && !win.closed) ? getFileName(win.location.href) : "";
- }
- catch (exc)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("reps.Window window closed?");
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "object",
-
- supportsObject: function(object)
- {
- return instanceOf(object, "Window");
- },
-
- browseObject: function(win, context)
- {
- openNewTab(win.location.href);
- return true;
- },
-
- persistObject: function(win, context)
- {
- return this.persistor;
- },
-
- persistor: function(context)
- {
- return context.window;
- },
-
- getTitle: function(win, context)
- {
- return "window";
- },
-
- getTooltip: function(win)
- {
- if (win && !win.closed)
- return win.location.href;
- }
-});
-
-// ************************************************************************************************
-
-this.Event = domplate(Firebug.Rep,
-{
- tag: TAG("$copyEventTag", {object: "$object|copyEvent"}),
-
- copyEventTag:
- OBJECTLINK("$object|summarizeEvent"),
-
- summarizeEvent: function(event)
- {
- var info = [event.type, ' '];
-
- var eventFamily = getEventFamily(event.type);
- if (eventFamily == "mouse")
- info.push("clientX=", event.clientX, ", clientY=", event.clientY);
- else if (eventFamily == "key")
- info.push("charCode=", event.charCode, ", keyCode=", event.keyCode);
-
- return info.join("");
- },
-
- copyEvent: function(event)
- {
- return new EventCopy(event);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "object",
-
- supportsObject: function(object)
- {
- //return object instanceof Event || object instanceof EventCopy;
- return instanceOf(object, "Event") || instanceOf(object, "EventCopy");
- },
-
- getTitle: function(event, context)
- {
- return "Event " + event.type;
- }
-});
-
-// ************************************************************************************************
-
-this.SourceLink = domplate(Firebug.Rep,
-{
- tag:
- OBJECTLINK({$collapsed: "$object|hideSourceLink"}, "$object|getSourceLinkTitle"),
-
- hideSourceLink: function(sourceLink)
- {
- return sourceLink ? sourceLink.href.indexOf("XPCSafeJSObjectWrapper") != -1 : true;
- },
-
- getSourceLinkTitle: function(sourceLink)
- {
- if (!sourceLink)
- return "";
-
- try
- {
- var fileName = getFileName(sourceLink.href);
- fileName = decodeURIComponent(fileName);
- fileName = cropString(fileName, 17);
- }
- catch(exc)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("reps.getSourceLinkTitle decodeURIComponent fails for \'"+fileName+"\': "+exc, exc);
- }
-
- return typeof sourceLink.line == "number" ?
- fileName + " (line " + sourceLink.line + ")" :
- fileName;
-
- // TODO: xxxpedro
- //return $STRF("Line", [fileName, sourceLink.line]);
- },
-
- copyLink: function(sourceLink)
- {
- copyToClipboard(sourceLink.href);
- },
-
- openInTab: function(sourceLink)
- {
- openNewTab(sourceLink.href);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "sourceLink",
-
- supportsObject: function(object)
- {
- return object instanceof SourceLink;
- },
-
- getTooltip: function(sourceLink)
- {
- return decodeURI(sourceLink.href);
- },
-
- inspectObject: function(sourceLink, context)
- {
- if (sourceLink.type == "js")
- {
- var scriptFile = getSourceFileByHref(sourceLink.href, context);
- if (scriptFile)
- return Firebug.chrome.select(sourceLink);
- }
- else if (sourceLink.type == "css")
- {
- // If an object is defined, treat it as the highest priority for
- // inspect actions
- if (sourceLink.object) {
- Firebug.chrome.select(sourceLink.object);
- return;
- }
-
- var stylesheet = getStyleSheetByHref(sourceLink.href, context);
- if (stylesheet)
- {
- var ownerNode = stylesheet.ownerNode;
- if (ownerNode)
- {
- Firebug.chrome.select(sourceLink, "html");
- return;
- }
-
- var panel = context.getPanel("stylesheet");
- if (panel && panel.getRuleByLine(stylesheet, sourceLink.line))
- return Firebug.chrome.select(sourceLink);
- }
- }
-
- // Fallback is to just open the view-source window on the file
- viewSource(sourceLink.href, sourceLink.line);
- },
-
- browseObject: function(sourceLink, context)
- {
- openNewTab(sourceLink.href);
- return true;
- },
-
- getContextMenuItems: function(sourceLink, target, context)
- {
- return [
- {label: "CopyLocation", command: bindFixed(this.copyLink, this, sourceLink) },
- "-",
- {label: "OpenInTab", command: bindFixed(this.openInTab, this, sourceLink) }
- ];
- }
-});
-
-// ************************************************************************************************
-
-this.SourceFile = domplate(this.SourceLink,
-{
- tag:
- OBJECTLINK({$collapsed: "$object|hideSourceLink"}, "$object|getSourceLinkTitle"),
-
- persistor: function(context, href)
- {
- return getSourceFileByHref(href, context);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "sourceFile",
-
- supportsObject: function(object)
- {
- return object instanceof SourceFile;
- },
-
- persistObject: function(sourceFile)
- {
- return bind(this.persistor, top, sourceFile.href);
- },
-
- browseObject: function(sourceLink, context)
- {
- },
-
- getTooltip: function(sourceFile)
- {
- return sourceFile.href;
- }
-});
-
-// ************************************************************************************************
-
-this.StackFrame = domplate(Firebug.Rep, // XXXjjb Since the repObject is fn the stack does not have correct line numbers
-{
- tag:
- OBJECTBLOCK(
- A({"class": "objectLink objectLink-function focusRow a11yFocus", _repObject: "$object.fn"}, "$object|getCallName"),
- " ( ",
- FOR("arg", "$object|argIterator",
- TAG("$arg.tag", {object: "$arg.value"}),
- SPAN({"class": "arrayComma"}, "$arg.delim")
- ),
- " )",
- SPAN({"class": "objectLink-sourceLink objectLink"}, "$object|getSourceLinkTitle")
- ),
-
- getCallName: function(frame)
- {
- //TODO: xxxpedro reps StackFrame
- return frame.name || "anonymous";
-
- //return getFunctionName(frame.script, frame.context);
- },
-
- getSourceLinkTitle: function(frame)
- {
- //TODO: xxxpedro reps StackFrame
- var fileName = cropString(getFileName(frame.href), 20);
- return fileName + (frame.lineNo ? " (line " + frame.lineNo + ")" : "");
-
- var fileName = cropString(getFileName(frame.href), 17);
- return $STRF("Line", [fileName, frame.lineNo]);
- },
-
- argIterator: function(frame)
- {
- if (!frame.args)
- return [];
-
- var items = [];
-
- for (var i = 0; i < frame.args.length; ++i)
- {
- var arg = frame.args[i];
-
- if (!arg)
- break;
-
- var rep = Firebug.getRep(arg.value);
- var tag = rep.shortTag ? rep.shortTag : rep.tag;
-
- var delim = (i == frame.args.length-1 ? "" : ", ");
-
- items.push({name: arg.name, value: arg.value, tag: tag, delim: delim});
- }
-
- return items;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "stackFrame",
-
- supportsObject: function(object)
- {
- return object instanceof StackFrame;
- },
-
- inspectObject: function(stackFrame, context)
- {
- var sourceLink = new SourceLink(stackFrame.href, stackFrame.lineNo, "js");
- Firebug.chrome.select(sourceLink);
- },
-
- getTooltip: function(stackFrame, context)
- {
- return $STRF("Line", [stackFrame.href, stackFrame.lineNo]);
- }
-
-});
-
-// ************************************************************************************************
-
-this.StackTrace = domplate(Firebug.Rep,
-{
- tag:
- FOR("frame", "$object.frames focusRow",
- TAG(this.StackFrame.tag, {object: "$frame"})
- ),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "stackTrace",
-
- supportsObject: function(object)
- {
- return object instanceof StackTrace;
- }
-});
-
-// ************************************************************************************************
-
-this.jsdStackFrame = domplate(Firebug.Rep,
-{
- inspectable: false,
-
- supportsObject: function(object)
- {
- return (object instanceof jsdIStackFrame) && (object.isValid);
- },
-
- getTitle: function(frame, context)
- {
- if (!frame.isValid) return "(invalid frame)"; // XXXjjb avoid frame.script == null
- return getFunctionName(frame.script, context);
- },
-
- getTooltip: function(frame, context)
- {
- if (!frame.isValid) return "(invalid frame)"; // XXXjjb avoid frame.script == null
- var sourceInfo = FBL.getSourceFileAndLineByScript(context, frame.script, frame);
- if (sourceInfo)
- return $STRF("Line", [sourceInfo.sourceFile.href, sourceInfo.lineNo]);
- else
- return $STRF("Line", [frame.script.fileName, frame.line]);
- },
-
- getContextMenuItems: function(frame, target, context)
- {
- var fn = frame.script.functionObject.getWrappedValue();
- return FirebugReps.Func.getContextMenuItems(fn, target, context, frame.script);
- }
-});
-
-// ************************************************************************************************
-
-this.ErrorMessage = domplate(Firebug.Rep,
-{
- tag:
- OBJECTBOX({
- $hasTwisty: "$object|hasStackTrace",
- $hasBreakSwitch: "$object|hasBreakSwitch",
- $breakForError: "$object|hasErrorBreak",
- _repObject: "$object",
- _stackTrace: "$object|getLastErrorStackTrace",
- onclick: "$onToggleError"},
-
- DIV({"class": "errorTitle a11yFocus", role : 'checkbox', 'aria-checked' : 'false'},
- "$object.message|getMessage"
- ),
- DIV({"class": "errorTrace"}),
- DIV({"class": "errorSourceBox errorSource-$object|getSourceType"},
- IMG({"class": "errorBreak a11yFocus", src:"blank.gif", role : 'checkbox', 'aria-checked':'false', title: "Break on this error"}),
- A({"class": "errorSource a11yFocus"}, "$object|getLine")
- ),
- TAG(this.SourceLink.tag, {object: "$object|getSourceLink"})
- ),
-
- getLastErrorStackTrace: function(error)
- {
- return error.trace;
- },
-
- hasStackTrace: function(error)
- {
- var url = error.href.toString();
- var fromCommandLine = (url.indexOf("XPCSafeJSObjectWrapper") != -1);
- return !fromCommandLine && error.trace;
- },
-
- hasBreakSwitch: function(error)
- {
- return error.href && error.lineNo > 0;
- },
-
- hasErrorBreak: function(error)
- {
- return fbs.hasErrorBreakpoint(error.href, error.lineNo);
- },
-
- getMessage: function(message)
- {
- var re = /\[Exception... "(.*?)" nsresult:/;
- var m = re.exec(message);
- return m ? m[1] : message;
- },
-
- getLine: function(error)
- {
- if (error.category == "js")
- {
- if (error.source)
- return cropString(error.source, 80);
- else if (error.href && error.href.indexOf("XPCSafeJSObjectWrapper") == -1)
- return cropString(error.getSourceLine(), 80);
- }
- },
-
- getSourceLink: function(error)
- {
- var ext = error.category == "css" ? "css" : "js";
- return error.lineNo ? new SourceLink(error.href, error.lineNo, ext) : null;
- },
-
- getSourceType: function(error)
- {
- // Errors occurring inside of HTML event handlers look like "foo.html (line 1)"
- // so let's try to skip those
- if (error.source)
- return "syntax";
- else if (error.lineNo == 1 && getFileExtension(error.href) != "js")
- return "none";
- else if (error.category == "css")
- return "none";
- else if (!error.href || !error.lineNo)
- return "none";
- else
- return "exec";
- },
-
- onToggleError: function(event)
- {
- var target = event.currentTarget;
- if (hasClass(event.target, "errorBreak"))
- {
- this.breakOnThisError(target.repObject);
- }
- else if (hasClass(event.target, "errorSource"))
- {
- var panel = Firebug.getElementPanel(event.target);
- this.inspectObject(target.repObject, panel.context);
- }
- else if (hasClass(event.target, "errorTitle"))
- {
- var traceBox = target.childNodes[1];
- toggleClass(target, "opened");
- event.target.setAttribute('aria-checked', hasClass(target, "opened"));
- if (hasClass(target, "opened"))
- {
- if (target.stackTrace)
- var node = FirebugReps.StackTrace.tag.append({object: target.stackTrace}, traceBox);
- if (Firebug.A11yModel.enabled)
- {
- var panel = Firebug.getElementPanel(event.target);
- dispatch([Firebug.A11yModel], "onLogRowContentCreated", [panel , traceBox]);
- }
- }
- else
- clearNode(traceBox);
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- copyError: function(error)
- {
- var message = [
- this.getMessage(error.message),
- error.href,
- "Line " + error.lineNo
- ];
- copyToClipboard(message.join("\n"));
- },
-
- breakOnThisError: function(error)
- {
- if (this.hasErrorBreak(error))
- Firebug.Debugger.clearErrorBreakpoint(error.href, error.lineNo);
- else
- Firebug.Debugger.setErrorBreakpoint(error.href, error.lineNo);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "errorMessage",
- inspectable: false,
-
- supportsObject: function(object)
- {
- return object instanceof ErrorMessage;
- },
-
- inspectObject: function(error, context)
- {
- var sourceLink = this.getSourceLink(error);
- FirebugReps.SourceLink.inspectObject(sourceLink, context);
- },
-
- getContextMenuItems: function(error, target, context)
- {
- var breakOnThisError = this.hasErrorBreak(error);
-
- var items = [
- {label: "CopyError", command: bindFixed(this.copyError, this, error) }
- ];
-
- if (error.category == "css")
- {
- items.push(
- "-",
- {label: "BreakOnThisError", type: "checkbox", checked: breakOnThisError,
- command: bindFixed(this.breakOnThisError, this, error) },
-
- optionMenu("BreakOnAllErrors", "breakOnErrors")
- );
- }
-
- return items;
- }
-});
-
-// ************************************************************************************************
-
-this.Assert = domplate(Firebug.Rep,
-{
- tag:
- DIV(
- DIV({"class": "errorTitle"}),
- DIV({"class": "assertDescription"})
- ),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "assert",
-
- inspectObject: function(error, context)
- {
- var sourceLink = this.getSourceLink(error);
- Firebug.chrome.select(sourceLink);
- },
-
- getContextMenuItems: function(error, target, context)
- {
- var breakOnThisError = this.hasErrorBreak(error);
-
- return [
- {label: "CopyError", command: bindFixed(this.copyError, this, error) },
- "-",
- {label: "BreakOnThisError", type: "checkbox", checked: breakOnThisError,
- command: bindFixed(this.breakOnThisError, this, error) },
- {label: "BreakOnAllErrors", type: "checkbox", checked: Firebug.breakOnErrors,
- command: bindFixed(this.breakOnAllErrors, this, error) }
- ];
- }
-});
-
-// ************************************************************************************************
-
-this.SourceText = domplate(Firebug.Rep,
-{
- tag:
- DIV(
- FOR("line", "$object|lineIterator",
- DIV({"class": "sourceRow", role : "presentation"},
- SPAN({"class": "sourceLine", role : "presentation"}, "$line.lineNo"),
- SPAN({"class": "sourceRowText", role : "presentation"}, "$line.text")
- )
- )
- ),
-
- lineIterator: function(sourceText)
- {
- var maxLineNoChars = (sourceText.lines.length + "").length;
- var list = [];
-
- for (var i = 0; i < sourceText.lines.length; ++i)
- {
- // Make sure all line numbers are the same width (with a fixed-width font)
- var lineNo = (i+1) + "";
- while (lineNo.length < maxLineNoChars)
- lineNo = " " + lineNo;
-
- list.push({lineNo: lineNo, text: sourceText.lines[i]});
- }
-
- return list;
- },
-
- getHTML: function(sourceText)
- {
- return getSourceLineRange(sourceText, 1, sourceText.lines.length);
- }
-});
-
-//************************************************************************************************
-this.nsIDOMHistory = domplate(Firebug.Rep,
-{
- tag:OBJECTBOX({onclick: "$showHistory"},
- OBJECTLINK("$object|summarizeHistory")
- ),
-
- className: "nsIDOMHistory",
-
- summarizeHistory: function(history)
- {
- try
- {
- var items = history.length;
- return items + " history entries";
- }
- catch(exc)
- {
- return "object does not support history (nsIDOMHistory)";
- }
- },
-
- showHistory: function(history)
- {
- try
- {
- var items = history.length; // if this throws, then unsupported
- Firebug.chrome.select(history);
- }
- catch (exc)
- {
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- supportsObject: function(object, type)
- {
- return (object instanceof Ci.nsIDOMHistory);
- }
-});
-
-// ************************************************************************************************
-this.ApplicationCache = domplate(Firebug.Rep,
-{
- tag:OBJECTBOX({onclick: "$showApplicationCache"},
- OBJECTLINK("$object|summarizeCache")
- ),
-
- summarizeCache: function(applicationCache)
- {
- try
- {
- return applicationCache.length + " items in offline cache";
- }
- catch(exc)
- {
- return "https://bugzilla.mozilla.org/show_bug.cgi?id=422264";
- }
- },
-
- showApplicationCache: function(event)
- {
- openNewTab("https://bugzilla.mozilla.org/show_bug.cgi?id=422264");
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "applicationCache",
-
- supportsObject: function(object, type)
- {
- if (Ci.nsIDOMOfflineResourceList)
- return (object instanceof Ci.nsIDOMOfflineResourceList);
- }
-
-});
-
-this.Storage = domplate(Firebug.Rep,
-{
- tag: OBJECTBOX({onclick: "$show"}, OBJECTLINK("$object|summarize")),
-
- summarize: function(storage)
- {
- return storage.length +" items in Storage";
- },
- show: function(storage)
- {
- openNewTab("http://dev.w3.org/html5/webstorage/#storage-0");
- },
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "Storage",
-
- supportsObject: function(object, type)
- {
- return (object instanceof Storage);
- }
-
-});
-
-// ************************************************************************************************
-Firebug.registerRep(
- //this.nsIDOMHistory, // make this early to avoid exceptions
- this.Undefined,
- this.Null,
- this.Number,
- this.String,
- this.Window,
- //this.ApplicationCache, // must come before Arr (array) else exceptions.
- //this.ErrorMessage,
- this.Element,
- //this.TextNode,
- this.Document,
- this.StyleSheet,
- this.Event,
- //this.SourceLink,
- //this.SourceFile,
- //this.StackTrace,
- //this.StackFrame,
- //this.jsdStackFrame,
- //this.jsdScript,
- //this.NetFile,
- this.Property,
- this.Except,
- this.Arr
-);
-
-Firebug.setDefaultReps(this.Func, this.Obj);
-
-}});
-
-// ************************************************************************************************
-/*
- * The following is http://developer.yahoo.com/yui/license.txt and applies to only code labeled "Yahoo BSD Source"
- * in only this file reps.js. John J. Barton June 2007.
- *
-Software License Agreement (BSD License)
-
-Copyright (c) 2006, Yahoo! Inc.
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms, with or without modification, are
-permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of Yahoo! Inc. nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of Yahoo! Inc.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- * /
- */
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-
-// ************************************************************************************************
-// Constants
-
-var saveTimeout = 400;
-var pageAmount = 10;
-
-// ************************************************************************************************
-// Globals
-
-var currentTarget = null;
-var currentGroup = null;
-var currentPanel = null;
-var currentEditor = null;
-
-var defaultEditor = null;
-
-var originalClassName = null;
-
-var originalValue = null;
-var defaultValue = null;
-var previousValue = null;
-
-var invalidEditor = false;
-var ignoreNextInput = false;
-
-// ************************************************************************************************
-
-Firebug.Editor = extend(Firebug.Module,
-{
- supportsStopEvent: true,
-
- dispatchName: "editor",
- tabCharacter: " ",
-
- startEditing: function(target, value, editor)
- {
- this.stopEditing();
-
- if (hasClass(target, "insertBefore") || hasClass(target, "insertAfter"))
- return;
-
- var panel = Firebug.getElementPanel(target);
- if (!panel.editable)
- return;
-
- if (FBTrace.DBG_EDITOR)
- FBTrace.sysout("editor.startEditing " + value, target);
-
- defaultValue = target.getAttribute("defaultValue");
- if (value == undefined)
- {
- var textContent = isIE ? "innerText" : "textContent";
- value = target[textContent];
- if (value == defaultValue)
- value = "";
- }
-
- originalValue = previousValue = value;
-
- invalidEditor = false;
- currentTarget = target;
- currentPanel = panel;
- currentGroup = getAncestorByClass(target, "editGroup");
-
- currentPanel.editing = true;
-
- var panelEditor = currentPanel.getEditor(target, value);
- currentEditor = editor ? editor : panelEditor;
- if (!currentEditor)
- currentEditor = getDefaultEditor(currentPanel);
-
- var inlineParent = getInlineParent(target);
- var targetSize = getOffsetSize(inlineParent);
-
- setClass(panel.panelNode, "editing");
- setClass(target, "editing");
- if (currentGroup)
- setClass(currentGroup, "editing");
-
- currentEditor.show(target, currentPanel, value, targetSize);
- //dispatch(this.fbListeners, "onBeginEditing", [currentPanel, currentEditor, target, value]);
- currentEditor.beginEditing(target, value);
- if (FBTrace.DBG_EDITOR)
- FBTrace.sysout("Editor start panel "+currentPanel.name);
- this.attachListeners(currentEditor, panel.context);
- },
-
- stopEditing: function(cancel)
- {
- if (!currentTarget)
- return;
-
- if (FBTrace.DBG_EDITOR)
- FBTrace.sysout("editor.stopEditing cancel:" + cancel+" saveTimeout: "+this.saveTimeout);
-
- clearTimeout(this.saveTimeout);
- delete this.saveTimeout;
-
- this.detachListeners(currentEditor, currentPanel.context);
-
- removeClass(currentPanel.panelNode, "editing");
- removeClass(currentTarget, "editing");
- if (currentGroup)
- removeClass(currentGroup, "editing");
-
- var value = currentEditor.getValue();
- if (value == defaultValue)
- value = "";
-
- var removeGroup = currentEditor.endEditing(currentTarget, value, cancel);
-
- try
- {
- if (cancel)
- {
- //dispatch([Firebug.A11yModel], 'onInlineEditorClose', [currentPanel, currentTarget, removeGroup && !originalValue]);
- if (value != originalValue)
- this.saveEditAndNotifyListeners(currentTarget, originalValue, previousValue);
-
- if (removeGroup && !originalValue && currentGroup)
- currentGroup.parentNode.removeChild(currentGroup);
- }
- else if (!value)
- {
- this.saveEditAndNotifyListeners(currentTarget, null, previousValue);
-
- if (removeGroup && currentGroup)
- currentGroup.parentNode.removeChild(currentGroup);
- }
- else
- this.save(value);
- }
- catch (exc)
- {
- //throw exc.message;
- //ERROR(exc);
- }
-
- currentEditor.hide();
- currentPanel.editing = false;
-
- //dispatch(this.fbListeners, "onStopEdit", [currentPanel, currentEditor, currentTarget]);
- //if (FBTrace.DBG_EDITOR)
- // FBTrace.sysout("Editor stop panel "+currentPanel.name);
-
- currentTarget = null;
- currentGroup = null;
- currentPanel = null;
- currentEditor = null;
- originalValue = null;
- invalidEditor = false;
-
- return value;
- },
-
- cancelEditing: function()
- {
- return this.stopEditing(true);
- },
-
- update: function(saveNow)
- {
- if (this.saveTimeout)
- clearTimeout(this.saveTimeout);
-
- invalidEditor = true;
-
- currentEditor.layout();
-
- if (saveNow)
- this.save();
- else
- {
- var context = currentPanel.context;
- this.saveTimeout = context.setTimeout(bindFixed(this.save, this), saveTimeout);
- if (FBTrace.DBG_EDITOR)
- FBTrace.sysout("editor.update saveTimeout: "+this.saveTimeout);
- }
- },
-
- save: function(value)
- {
- if (!invalidEditor)
- return;
-
- if (value == undefined)
- value = currentEditor.getValue();
- if (FBTrace.DBG_EDITOR)
- FBTrace.sysout("editor.save saveTimeout: "+this.saveTimeout+" currentPanel: "+(currentPanel?currentPanel.name:"null"));
- try
- {
- this.saveEditAndNotifyListeners(currentTarget, value, previousValue);
-
- previousValue = value;
- invalidEditor = false;
- }
- catch (exc)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("editor.save FAILS "+exc, exc);
- }
- },
-
- saveEditAndNotifyListeners: function(currentTarget, value, previousValue)
- {
- currentEditor.saveEdit(currentTarget, value, previousValue);
- //dispatch(this.fbListeners, "onSaveEdit", [currentPanel, currentEditor, currentTarget, value, previousValue]);
- },
-
- setEditTarget: function(element)
- {
- if (!element)
- {
- dispatch([Firebug.A11yModel], 'onInlineEditorClose', [currentPanel, currentTarget, true]);
- this.stopEditing();
- }
- else if (hasClass(element, "insertBefore"))
- this.insertRow(element, "before");
- else if (hasClass(element, "insertAfter"))
- this.insertRow(element, "after");
- else
- this.startEditing(element);
- },
-
- tabNextEditor: function()
- {
- if (!currentTarget)
- return;
-
- var value = currentEditor.getValue();
- var nextEditable = currentTarget;
- do
- {
- nextEditable = !value && currentGroup
- ? getNextOutsider(nextEditable, currentGroup)
- : getNextByClass(nextEditable, "editable");
- }
- while (nextEditable && !nextEditable.offsetHeight);
-
- this.setEditTarget(nextEditable);
- },
-
- tabPreviousEditor: function()
- {
- if (!currentTarget)
- return;
-
- var value = currentEditor.getValue();
- var prevEditable = currentTarget;
- do
- {
- prevEditable = !value && currentGroup
- ? getPreviousOutsider(prevEditable, currentGroup)
- : getPreviousByClass(prevEditable, "editable");
- }
- while (prevEditable && !prevEditable.offsetHeight);
-
- this.setEditTarget(prevEditable);
- },
-
- insertRow: function(relative, insertWhere)
- {
- var group =
- relative || getAncestorByClass(currentTarget, "editGroup") || currentTarget;
- var value = this.stopEditing();
-
- currentPanel = Firebug.getElementPanel(group);
-
- currentEditor = currentPanel.getEditor(group, value);
- if (!currentEditor)
- currentEditor = getDefaultEditor(currentPanel);
-
- currentGroup = currentEditor.insertNewRow(group, insertWhere);
- if (!currentGroup)
- return;
-
- var editable = hasClass(currentGroup, "editable")
- ? currentGroup
- : getNextByClass(currentGroup, "editable");
-
- if (editable)
- this.setEditTarget(editable);
- },
-
- insertRowForObject: function(relative)
- {
- var container = getAncestorByClass(relative, "insertInto");
- if (container)
- {
- relative = getChildByClass(container, "insertBefore");
- if (relative)
- this.insertRow(relative, "before");
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- attachListeners: function(editor, context)
- {
- var win = isIE ?
- currentTarget.ownerDocument.parentWindow :
- currentTarget.ownerDocument.defaultView;
-
- addEvent(win, "resize", this.onResize);
- addEvent(win, "blur", this.onBlur);
-
- var chrome = Firebug.chrome;
-
- this.listeners = [
- chrome.keyCodeListen("ESCAPE", null, bind(this.cancelEditing, this))
- ];
-
- if (editor.arrowCompletion)
- {
- this.listeners.push(
- chrome.keyCodeListen("UP", null, bindFixed(editor.completeValue, editor, -1)),
- chrome.keyCodeListen("DOWN", null, bindFixed(editor.completeValue, editor, 1)),
- chrome.keyCodeListen("PAGE_UP", null, bindFixed(editor.completeValue, editor, -pageAmount)),
- chrome.keyCodeListen("PAGE_DOWN", null, bindFixed(editor.completeValue, editor, pageAmount))
- );
- }
-
- if (currentEditor.tabNavigation)
- {
- this.listeners.push(
- chrome.keyCodeListen("RETURN", null, bind(this.tabNextEditor, this)),
- chrome.keyCodeListen("RETURN", isControl, bind(this.insertRow, this, null, "after")),
- chrome.keyCodeListen("TAB", null, bind(this.tabNextEditor, this)),
- chrome.keyCodeListen("TAB", isShift, bind(this.tabPreviousEditor, this))
- );
- }
- else if (currentEditor.multiLine)
- {
- this.listeners.push(
- chrome.keyCodeListen("TAB", null, insertTab)
- );
- }
- else
- {
- this.listeners.push(
- chrome.keyCodeListen("RETURN", null, bindFixed(this.stopEditing, this))
- );
-
- if (currentEditor.tabCompletion)
- {
- this.listeners.push(
- chrome.keyCodeListen("TAB", null, bind(editor.completeValue, editor, 1)),
- chrome.keyCodeListen("TAB", isShift, bind(editor.completeValue, editor, -1))
- );
- }
- }
- },
-
- detachListeners: function(editor, context)
- {
- if (!this.listeners)
- return;
-
- var win = isIE ?
- currentTarget.ownerDocument.parentWindow :
- currentTarget.ownerDocument.defaultView;
-
- removeEvent(win, "resize", this.onResize);
- removeEvent(win, "blur", this.onBlur);
-
- var chrome = Firebug.chrome;
- if (chrome)
- {
- for (var i = 0; i < this.listeners.length; ++i)
- chrome.keyIgnore(this.listeners[i]);
- }
-
- delete this.listeners;
- },
-
- onResize: function(event)
- {
- currentEditor.layout(true);
- },
-
- onBlur: function(event)
- {
- if (currentEditor.enterOnBlur && isAncestor(event.target, currentEditor.box))
- this.stopEditing();
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // extends Module
-
- initialize: function()
- {
- Firebug.Module.initialize.apply(this, arguments);
-
- this.onResize = bindFixed(this.onResize, this);
- this.onBlur = bind(this.onBlur, this);
- },
-
- disable: function()
- {
- this.stopEditing();
- },
-
- showContext: function(browser, context)
- {
- this.stopEditing();
- },
-
- showPanel: function(browser, panel)
- {
- this.stopEditing();
- }
-});
-
-// ************************************************************************************************
-// BaseEditor
-
-Firebug.BaseEditor = extend(Firebug.MeasureBox,
-{
- getValue: function()
- {
- },
-
- setValue: function(value)
- {
- },
-
- show: function(target, panel, value, textSize, targetSize)
- {
- },
-
- hide: function()
- {
- },
-
- layout: function(forceAll)
- {
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Support for context menus within inline editors.
-
- getContextMenuItems: function(target)
- {
- var items = [];
- items.push({label: "Cut", commandID: "cmd_cut"});
- items.push({label: "Copy", commandID: "cmd_copy"});
- items.push({label: "Paste", commandID: "cmd_paste"});
- return items;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Editor Module listeners will get "onBeginEditing" just before this call
-
- beginEditing: function(target, value)
- {
- },
-
- // Editor Module listeners will get "onSaveEdit" just after this call
- saveEdit: function(target, value, previousValue)
- {
- },
-
- endEditing: function(target, value, cancel)
- {
- // Remove empty groups by default
- return true;
- },
-
- insertNewRow: function(target, insertWhere)
- {
- }
-});
-
-// ************************************************************************************************
-// InlineEditor
-
-// basic inline editor attributes
-var inlineEditorAttributes = {
- "class": "textEditorInner",
-
- type: "text",
- spellcheck: "false",
-
- onkeypress: "$onKeyPress",
-
- onoverflow: "$onOverflow",
- oncontextmenu: "$onContextMenu"
-};
-
-// IE does not support the oninput event, so we're using the onkeydown to signalize
-// the relevant keyboard events, and the onpropertychange to actually handle the
-// input event, which should happen after the onkeydown event is fired and after the
-// value of the input is updated, but before the onkeyup and before the input (with the
-// new value) is rendered
-if (isIE)
-{
- inlineEditorAttributes.onpropertychange = "$onInput";
- inlineEditorAttributes.onkeydown = "$onKeyDown";
-}
-// for other browsers we use the oninput event
-else
-{
- inlineEditorAttributes.oninput = "$onInput";
-}
-
-Firebug.InlineEditor = function(doc)
-{
- this.initializeInline(doc);
-};
-
-Firebug.InlineEditor.prototype = domplate(Firebug.BaseEditor,
-{
- enterOnBlur: true,
- outerMargin: 8,
- shadowExpand: 7,
-
- tag:
- DIV({"class": "inlineEditor"},
- DIV({"class": "textEditorTop1"},
- DIV({"class": "textEditorTop2"})
- ),
- DIV({"class": "textEditorInner1"},
- DIV({"class": "textEditorInner2"},
- INPUT(
- inlineEditorAttributes
- )
- )
- ),
- DIV({"class": "textEditorBottom1"},
- DIV({"class": "textEditorBottom2"})
- )
- ),
-
- inputTag :
- INPUT({"class": "textEditorInner", type: "text",
- /*oninput: "$onInput",*/ onkeypress: "$onKeyPress", onoverflow: "$onOverflow"}
- ),
-
- expanderTag:
- IMG({"class": "inlineExpander", src: "blank.gif"}),
-
- initialize: function()
- {
- this.fixedWidth = false;
- this.completeAsYouType = true;
- this.tabNavigation = true;
- this.multiLine = false;
- this.tabCompletion = false;
- this.arrowCompletion = true;
- this.noWrap = true;
- this.numeric = false;
- },
-
- destroy: function()
- {
- this.destroyInput();
- },
-
- initializeInline: function(doc)
- {
- if (FBTrace.DBG_EDITOR)
- FBTrace.sysout("Firebug.InlineEditor initializeInline()");
-
- //this.box = this.tag.replace({}, doc, this);
- this.box = this.tag.append({}, doc.body, this);
-
- //this.input = this.box.childNodes[1].firstChild.firstChild; // XXXjjb childNode[1] required
- this.input = this.box.getElementsByTagName("input")[0];
-
- if (isIElt8)
- {
- this.input.style.top = "-8px";
- }
-
- this.expander = this.expanderTag.replace({}, doc, this);
- this.initialize();
- },
-
- destroyInput: function()
- {
- // XXXjoe Need to remove input/keypress handlers to avoid leaks
- },
-
- getValue: function()
- {
- return this.input.value;
- },
-
- setValue: function(value)
- {
- // It's only a one-line editor, so new lines shouldn't be allowed
- return this.input.value = stripNewLines(value);
- },
-
- show: function(target, panel, value, targetSize)
- {
- //dispatch([Firebug.A11yModel], "onInlineEditorShow", [panel, this]);
- this.target = target;
- this.panel = panel;
-
- this.targetSize = targetSize;
-
- // TODO: xxxpedro editor
- //this.targetOffset = getClientOffset(target);
-
- // Some browsers (IE, Google Chrome and Safari) will have problem trying to get the
- // offset values of invisible elements, or empty elements. So, in order to get the
- // correct values, we temporary inject a character in the innerHTML of the empty element,
- // then we get the offset values, and next, we restore the original innerHTML value.
- var innerHTML = target.innerHTML;
- var isEmptyElement = !innerHTML;
- if (isEmptyElement)
- target.innerHTML = ".";
-
- // Get the position of the target element (that is about to be edited)
- this.targetOffset =
- {
- x: target.offsetLeft,
- y: target.offsetTop
- };
-
- // Restore the original innerHTML value of the empty element
- if (isEmptyElement)
- target.innerHTML = innerHTML;
-
- this.originalClassName = this.box.className;
-
- var classNames = target.className.split(" ");
- for (var i = 0; i < classNames.length; ++i)
- setClass(this.box, "editor-" + classNames[i]);
-
- // Make the editor match the target's font style
- copyTextStyles(target, this.box);
-
- this.setValue(value);
-
- if (this.fixedWidth)
- this.updateLayout(true);
- else
- {
- this.startMeasuring(target);
- this.textSize = this.measureInputText(value);
-
- // Correct the height of the box to make the funky CSS drop-shadow line up
- var parent = this.input.parentNode;
- if (hasClass(parent, "textEditorInner2"))
- {
- var yDiff = this.textSize.height - this.shadowExpand;
-
- // IE6 height offset
- if (isIE6)
- yDiff -= 2;
-
- parent.style.height = yDiff + "px";
- parent.parentNode.style.height = yDiff + "px";
- }
-
- this.updateLayout(true);
- }
-
- this.getAutoCompleter().reset();
-
- if (isIElt8)
- panel.panelNode.appendChild(this.box);
- else
- target.offsetParent.appendChild(this.box);
-
- //console.log(target);
- //this.input.select(); // it's called bellow, with setTimeout
-
- if (isIE)
- {
- // reset input style
- this.input.style.fontFamily = "Monospace";
- this.input.style.fontSize = "11px";
- }
-
- // Insert the "expander" to cover the target element with white space
- if (!this.fixedWidth)
- {
- copyBoxStyles(target, this.expander);
-
- target.parentNode.replaceChild(this.expander, target);
- collapse(target, true);
- this.expander.parentNode.insertBefore(target, this.expander);
- }
-
- //TODO: xxxpedro
- //scrollIntoCenterView(this.box, null, true);
-
- // Display the editor after change its size and position to avoid flickering
- this.box.style.display = "block";
-
- // we need to call input.focus() and input.select() with a timeout,
- // otherwise it won't work on all browsers due to timing issues
- var self = this;
- setTimeout(function(){
- self.input.focus();
- self.input.select();
- },0);
- },
-
- hide: function()
- {
- this.box.className = this.originalClassName;
-
- if (!this.fixedWidth)
- {
- this.stopMeasuring();
-
- collapse(this.target, false);
-
- if (this.expander.parentNode)
- this.expander.parentNode.removeChild(this.expander);
- }
-
- if (this.box.parentNode)
- {
- ///setSelectionRange(this.input, 0, 0);
- this.input.blur();
-
- this.box.parentNode.removeChild(this.box);
- }
-
- delete this.target;
- delete this.panel;
- },
-
- layout: function(forceAll)
- {
- if (!this.fixedWidth)
- this.textSize = this.measureInputText(this.input.value);
-
- if (forceAll)
- this.targetOffset = getClientOffset(this.expander);
-
- this.updateLayout(false, forceAll);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- beginEditing: function(target, value)
- {
- },
-
- saveEdit: function(target, value, previousValue)
- {
- },
-
- endEditing: function(target, value, cancel)
- {
- // Remove empty groups by default
- return true;
- },
-
- insertNewRow: function(target, insertWhere)
- {
- },
-
- advanceToNext: function(target, charCode)
- {
- return false;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- getAutoCompleteRange: function(value, offset)
- {
- },
-
- getAutoCompleteList: function(preExpr, expr, postExpr)
- {
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- getAutoCompleter: function()
- {
- if (!this.autoCompleter)
- {
- this.autoCompleter = new Firebug.AutoCompleter(null,
- bind(this.getAutoCompleteRange, this), bind(this.getAutoCompleteList, this),
- true, false);
- }
-
- return this.autoCompleter;
- },
-
- completeValue: function(amt)
- {
- //console.log("completeValue");
-
- var selectRangeCallback = this.getAutoCompleter().complete(currentPanel.context, this.input, true, amt < 0);
-
- if (selectRangeCallback)
- {
- Firebug.Editor.update(true);
-
- // We need to select the editor text after calling update in Safari/Chrome,
- // otherwise the text won't be selected
- if (isSafari)
- setTimeout(selectRangeCallback,0);
- else
- selectRangeCallback();
- }
- else
- this.incrementValue(amt);
- },
-
- incrementValue: function(amt)
- {
- var value = this.input.value;
-
- // TODO: xxxpedro editor
- if (isIE)
- var start = getInputSelectionStart(this.input), end = start;
- else
- var start = this.input.selectionStart, end = this.input.selectionEnd;
-
- //debugger;
- var range = this.getAutoCompleteRange(value, start);
- if (!range || range.type != "int")
- range = {start: 0, end: value.length-1};
-
- var expr = value.substr(range.start, range.end-range.start+1);
- preExpr = value.substr(0, range.start);
- postExpr = value.substr(range.end+1);
-
- // See if the value is an integer, and if so increment it
- var intValue = parseInt(expr);
- if (!!intValue || intValue == 0)
- {
- var m = /\d+/.exec(expr);
- var digitPost = expr.substr(m.index+m[0].length);
-
- var completion = intValue-amt;
- this.input.value = preExpr + completion + digitPost + postExpr;
-
- setSelectionRange(this.input, start, end);
-
- Firebug.Editor.update(true);
-
- return true;
- }
- else
- return false;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- onKeyPress: function(event)
- {
- //console.log("onKeyPress", event);
- if (event.keyCode == 27 && !this.completeAsYouType)
- {
- var reverted = this.getAutoCompleter().revert(this.input);
- if (reverted)
- cancelEvent(event);
- }
- else if (event.charCode && this.advanceToNext(this.target, event.charCode))
- {
- Firebug.Editor.tabNextEditor();
- cancelEvent(event);
- }
- else
- {
- if (this.numeric && event.charCode && (event.charCode < 48 || event.charCode > 57)
- && event.charCode != 45 && event.charCode != 46)
- FBL.cancelEvent(event);
- else
- {
- // If the user backspaces, don't autocomplete after the upcoming input event
- this.ignoreNextInput = event.keyCode == 8;
- }
- }
- },
-
- onOverflow: function()
- {
- this.updateLayout(false, false, 3);
- },
-
- onKeyDown: function(event)
- {
- //console.log("onKeyDown", event.keyCode);
- if (event.keyCode > 46 || event.keyCode == 32 || event.keyCode == 8)
- {
- this.keyDownPressed = true;
- }
- },
-
- onInput: function(event)
- {
- //debugger;
-
- // skip not relevant onpropertychange calls on IE
- if (isIE)
- {
- if (event.propertyName != "value" || !isVisible(this.input) || !this.keyDownPressed)
- return;
-
- this.keyDownPressed = false;
- }
-
- //console.log("onInput", event);
- //console.trace();
-
- var selectRangeCallback;
-
- if (this.ignoreNextInput)
- {
- this.ignoreNextInput = false;
- this.getAutoCompleter().reset();
- }
- else if (this.completeAsYouType)
- selectRangeCallback = this.getAutoCompleter().complete(currentPanel.context, this.input, false);
- else
- this.getAutoCompleter().reset();
-
- Firebug.Editor.update();
-
- if (selectRangeCallback)
- {
- // We need to select the editor text after calling update in Safari/Chrome,
- // otherwise the text won't be selected
- if (isSafari)
- setTimeout(selectRangeCallback,0);
- else
- selectRangeCallback();
- }
- },
-
- onContextMenu: function(event)
- {
- cancelEvent(event);
-
- var popup = $("fbInlineEditorPopup");
- FBL.eraseNode(popup);
-
- var target = event.target || event.srcElement;
- var menu = this.getContextMenuItems(target);
- if (menu)
- {
- for (var i = 0; i < menu.length; ++i)
- FBL.createMenuItem(popup, menu[i]);
- }
-
- if (!popup.firstChild)
- return false;
-
- popup.openPopupAtScreen(event.screenX, event.screenY, true);
- return true;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- updateLayout: function(initial, forceAll, extraWidth)
- {
- if (this.fixedWidth)
- {
- this.box.style.left = (this.targetOffset.x) + "px";
- this.box.style.top = (this.targetOffset.y) + "px";
-
- var w = this.target.offsetWidth;
- var h = this.target.offsetHeight;
- this.input.style.width = w + "px";
- this.input.style.height = (h-3) + "px";
- }
- else
- {
- if (initial || forceAll)
- {
- this.box.style.left = this.targetOffset.x + "px";
- this.box.style.top = this.targetOffset.y + "px";
- }
-
- var approxTextWidth = this.textSize.width;
- var maxWidth = (currentPanel.panelNode.scrollWidth - this.targetOffset.x)
- - this.outerMargin;
-
- var wrapped = initial
- ? this.noWrap && this.targetSize.height > this.textSize.height+3
- : this.noWrap && approxTextWidth > maxWidth;
-
- if (wrapped)
- {
- var style = isIE ?
- this.target.currentStyle :
- this.target.ownerDocument.defaultView.getComputedStyle(this.target, "");
-
- targetMargin = parseInt(style.marginLeft) + parseInt(style.marginRight);
-
- // Make the width fit the remaining x-space from the offset to the far right
- approxTextWidth = maxWidth - targetMargin;
-
- this.input.style.width = "100%";
- this.box.style.width = approxTextWidth + "px";
- }
- else
- {
- // Make the input one character wider than the text value so that
- // typing does not ever cause the textbox to scroll
- var charWidth = this.measureInputText('m').width;
-
- // Sometimes we need to make the editor a little wider, specifically when
- // an overflow happens, otherwise it will scroll off some text on the left
- if (extraWidth)
- charWidth *= extraWidth;
-
- var inputWidth = approxTextWidth + charWidth;
-
- if (initial)
- {
- if (isIE)
- {
- // TODO: xxxpedro
- var xDiff = 13;
- this.box.style.width = (inputWidth + xDiff) + "px";
- }
- else
- this.box.style.width = "auto";
- }
- else
- {
- // TODO: xxxpedro
- var xDiff = isIE ? 13: this.box.scrollWidth - this.input.offsetWidth;
- this.box.style.width = (inputWidth + xDiff) + "px";
- }
-
- this.input.style.width = inputWidth + "px";
- }
-
- this.expander.style.width = approxTextWidth + "px";
- this.expander.style.height = Math.max(this.textSize.height-3,0) + "px";
- }
-
- if (forceAll)
- scrollIntoCenterView(this.box, null, true);
- }
-});
-
-// ************************************************************************************************
-// Autocompletion
-
-Firebug.AutoCompleter = function(getExprOffset, getRange, evaluator, selectMode, caseSensitive)
-{
- var candidates = null;
- var originalValue = null;
- var originalOffset = -1;
- var lastExpr = null;
- var lastOffset = -1;
- var exprOffset = 0;
- var lastIndex = 0;
- var preParsed = null;
- var preExpr = null;
- var postExpr = null;
-
- this.revert = function(textBox)
- {
- if (originalOffset != -1)
- {
- textBox.value = originalValue;
-
- setSelectionRange(textBox, originalOffset, originalOffset);
-
- this.reset();
- return true;
- }
- else
- {
- this.reset();
- return false;
- }
- };
-
- this.reset = function()
- {
- candidates = null;
- originalValue = null;
- originalOffset = -1;
- lastExpr = null;
- lastOffset = 0;
- exprOffset = 0;
- };
-
- this.complete = function(context, textBox, cycle, reverse)
- {
- //console.log("complete", context, textBox, cycle, reverse);
- // TODO: xxxpedro important port to firebug (variable leak)
- //var value = lastValue = textBox.value;
- var value = textBox.value;
-
- //var offset = textBox.selectionStart;
- var offset = getInputSelectionStart(textBox);
-
- // The result of selectionStart() in Safari/Chrome is 1 unit less than the result
- // in Firefox. Therefore, we need to manually adjust the value here.
- if (isSafari && !cycle && offset >= 0) offset++;
-
- if (!selectMode && originalOffset != -1)
- offset = originalOffset;
-
- if (!candidates || !cycle || offset != lastOffset)
- {
- originalOffset = offset;
- originalValue = value;
-
- // Find the part of the string that will be parsed
- var parseStart = getExprOffset ? getExprOffset(value, offset, context) : 0;
- preParsed = value.substr(0, parseStart);
- var parsed = value.substr(parseStart);
-
- // Find the part of the string that is being completed
- var range = getRange ? getRange(parsed, offset-parseStart, context) : null;
- if (!range)
- range = {start: 0, end: parsed.length-1 };
-
- var expr = parsed.substr(range.start, range.end-range.start+1);
- preExpr = parsed.substr(0, range.start);
- postExpr = parsed.substr(range.end+1);
- exprOffset = parseStart + range.start;
-
- if (!cycle)
- {
- if (!expr)
- return;
- else if (lastExpr && lastExpr.indexOf(expr) != 0)
- {
- candidates = null;
- }
- else if (lastExpr && lastExpr.length >= expr.length)
- {
- candidates = null;
- lastExpr = expr;
- return;
- }
- }
-
- lastExpr = expr;
- lastOffset = offset;
-
- var searchExpr;
-
- // Check if the cursor is at the very right edge of the expression, or
- // somewhere in the middle of it
- if (expr && offset != parseStart+range.end+1)
- {
- if (cycle)
- {
- // We are in the middle of the expression, but we can
- // complete by cycling to the next item in the values
- // list after the expression
- offset = range.start;
- searchExpr = expr;
- expr = "";
- }
- else
- {
- // We can't complete unless we are at the ridge edge
- return;
- }
- }
-
- var values = evaluator(preExpr, expr, postExpr, context);
- if (!values)
- return;
-
- if (expr)
- {
- // Filter the list of values to those which begin with expr. We
- // will then go on to complete the first value in the resulting list
- candidates = [];
-
- if (caseSensitive)
- {
- for (var i = 0; i < values.length; ++i)
- {
- var name = values[i];
- if (name.indexOf && name.indexOf(expr) == 0)
- candidates.push(name);
- }
- }
- else
- {
- var lowerExpr = caseSensitive ? expr : expr.toLowerCase();
- for (var i = 0; i < values.length; ++i)
- {
- var name = values[i];
- if (name.indexOf && name.toLowerCase().indexOf(lowerExpr) == 0)
- candidates.push(name);
- }
- }
-
- lastIndex = reverse ? candidates.length-1 : 0;
- }
- else if (searchExpr)
- {
- var searchIndex = -1;
-
- // Find the first instance of searchExpr in the values list. We
- // will then complete the string that is found
- if (caseSensitive)
- {
- searchIndex = values.indexOf(expr);
- }
- else
- {
- var lowerExpr = searchExpr.toLowerCase();
- for (var i = 0; i < values.length; ++i)
- {
- var name = values[i];
- if (name && name.toLowerCase().indexOf(lowerExpr) == 0)
- {
- searchIndex = i;
- break;
- }
- }
- }
-
- // Nothing found, so there's nothing to complete to
- if (searchIndex == -1)
- return this.reset();
-
- expr = searchExpr;
- candidates = cloneArray(values);
- lastIndex = searchIndex;
- }
- else
- {
- expr = "";
- candidates = [];
- for (var i = 0; i < values.length; ++i)
- {
- if (values[i].substr)
- candidates.push(values[i]);
- }
- lastIndex = -1;
- }
- }
-
- if (cycle)
- {
- expr = lastExpr;
- lastIndex += reverse ? -1 : 1;
- }
-
- if (!candidates.length)
- return;
-
- if (lastIndex >= candidates.length)
- lastIndex = 0;
- else if (lastIndex < 0)
- lastIndex = candidates.length-1;
-
- var completion = candidates[lastIndex];
- var preCompletion = expr.substr(0, offset-exprOffset);
- var postCompletion = completion.substr(offset-exprOffset);
-
- textBox.value = preParsed + preExpr + preCompletion + postCompletion + postExpr;
- var offsetEnd = preParsed.length + preExpr.length + completion.length;
-
- // TODO: xxxpedro remove the following commented code, if the lib.setSelectionRange()
- // is working well.
- /*
- if (textBox.setSelectionRange)
- {
- // we must select the range with a timeout, otherwise the text won't
- // be properly selected (because after this function executes, the editor's
- // input will be resized to fit the whole text)
- setTimeout(function(){
- if (selectMode)
- textBox.setSelectionRange(offset, offsetEnd);
- else
- textBox.setSelectionRange(offsetEnd, offsetEnd);
- },0);
- }
- /**/
-
- // we must select the range with a timeout, otherwise the text won't
- // be properly selected (because after this function executes, the editor's
- // input will be resized to fit the whole text)
- /*
- setTimeout(function(){
- if (selectMode)
- setSelectionRange(textBox, offset, offsetEnd);
- else
- setSelectionRange(textBox, offsetEnd, offsetEnd);
- },0);
-
- return true;
- /**/
-
- // The editor text should be selected only after calling the editor.update()
- // in Safari/Chrome, otherwise the text won't be selected. So, we're returning
- // a function to be called later (in the proper time for all browsers).
- //
- // TODO: xxxpedro see if we can move the editor.update() calls to here, and avoid
- // returning a closure. the complete() function seems to be called only twice in
- // editor.js. See if this function is called anywhere else (like css.js for example).
- return function(){
- //console.log("autocomplete ", textBox, offset, offsetEnd);
-
- if (selectMode)
- setSelectionRange(textBox, offset, offsetEnd);
- else
- setSelectionRange(textBox, offsetEnd, offsetEnd);
- };
- /**/
- };
-};
-
-// ************************************************************************************************
-// Local Helpers
-
-var getDefaultEditor = function getDefaultEditor(panel)
-{
- if (!defaultEditor)
- {
- var doc = panel.document;
- defaultEditor = new Firebug.InlineEditor(doc);
- }
-
- return defaultEditor;
-}
-
-/**
- * An outsider is the first element matching the stepper element that
- * is not an child of group. Elements tagged with insertBefore or insertAfter
- * classes are also excluded from these results unless they are the sibling
- * of group, relative to group's parent editGroup. This allows for the proper insertion
- * rows when groups are nested.
- */
-var getOutsider = function getOutsider(element, group, stepper)
-{
- var parentGroup = getAncestorByClass(group.parentNode, "editGroup");
- var next;
- do
- {
- next = stepper(next || element);
- }
- while (isAncestor(next, group) || isGroupInsert(next, parentGroup));
-
- return next;
-}
-
-var isGroupInsert = function isGroupInsert(next, group)
-{
- return (!group || isAncestor(next, group))
- && (hasClass(next, "insertBefore") || hasClass(next, "insertAfter"));
-}
-
-var getNextOutsider = function getNextOutsider(element, group)
-{
- return getOutsider(element, group, bind(getNextByClass, FBL, "editable"));
-}
-
-var getPreviousOutsider = function getPreviousOutsider(element, group)
-{
- return getOutsider(element, group, bind(getPreviousByClass, FBL, "editable"));
-}
-
-var getInlineParent = function getInlineParent(element)
-{
- var lastInline = element;
- for (; element; element = element.parentNode)
- {
- //var s = element.ownerDocument.defaultView.getComputedStyle(element, "");
- var s = isIE ?
- element.currentStyle :
- element.ownerDocument.defaultView.getComputedStyle(element, "");
-
- if (s.display != "inline")
- return lastInline;
- else
- lastInline = element;
- }
- return null;
-}
-
-var insertTab = function insertTab()
-{
- insertTextIntoElement(currentEditor.input, Firebug.Editor.tabCharacter);
-}
-
-// ************************************************************************************************
-
-Firebug.registerModule(Firebug.Editor);
-
-// ************************************************************************************************
-
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-if (Env.Options.disableXHRListener)
- return;
-
-// ************************************************************************************************
-// XHRSpy
-
-var XHRSpy = function()
-{
- this.requestHeaders = [];
- this.responseHeaders = [];
-};
-
-XHRSpy.prototype =
-{
- method: null,
- url: null,
- async: null,
-
- xhrRequest: null,
-
- href: null,
-
- loaded: false,
-
- logRow: null,
-
- responseText: null,
-
- requestHeaders: null,
- responseHeaders: null,
-
- sourceLink: null, // {href:"file.html", line: 22}
-
- getURL: function()
- {
- return this.href;
- }
-};
-
-// ************************************************************************************************
-// XMLHttpRequestWrapper
-
-var XMLHttpRequestWrapper = function(activeXObject)
-{
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // XMLHttpRequestWrapper internal variables
-
- var xhrRequest = typeof activeXObject != "undefined" ?
- activeXObject :
- new _XMLHttpRequest(),
-
- spy = new XHRSpy(),
-
- self = this,
-
- reqType,
- reqUrl,
- reqStartTS;
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // XMLHttpRequestWrapper internal methods
-
- var updateSelfPropertiesIgnore = {
- abort: 1,
- channel: 1,
- getAllResponseHeaders: 1,
- getInterface: 1,
- getResponseHeader: 1,
- mozBackgroundRequest: 1,
- multipart: 1,
- onreadystatechange: 1,
- open: 1,
- send: 1,
- setRequestHeader: 1
- };
-
- var updateSelfProperties = function()
- {
- if (supportsXHRIterator)
- {
- for (var propName in xhrRequest)
- {
- if (propName in updateSelfPropertiesIgnore)
- continue;
-
- try
- {
- var propValue = xhrRequest[propName];
-
- if (propValue && !isFunction(propValue))
- self[propName] = propValue;
- }
- catch(E)
- {
- //console.log(propName, E.message);
- }
- }
- }
- else
- {
- // will fail to read these xhrRequest properties if the request is not completed
- if (xhrRequest.readyState == 4)
- {
- self.status = xhrRequest.status;
- self.statusText = xhrRequest.statusText;
- self.responseText = xhrRequest.responseText;
- self.responseXML = xhrRequest.responseXML;
- }
- }
- };
-
- var updateXHRPropertiesIgnore = {
- channel: 1,
- onreadystatechange: 1,
- readyState: 1,
- responseBody: 1,
- responseText: 1,
- responseXML: 1,
- status: 1,
- statusText: 1,
- upload: 1
- };
-
- var updateXHRProperties = function()
- {
- for (var propName in self)
- {
- if (propName in updateXHRPropertiesIgnore)
- continue;
-
- try
- {
- var propValue = self[propName];
-
- if (propValue && !xhrRequest[propName])
- {
- xhrRequest[propName] = propValue;
- }
- }
- catch(E)
- {
- //console.log(propName, E.message);
- }
- }
- };
-
- var logXHR = function()
- {
- var row = Firebug.Console.log(spy, null, "spy", Firebug.Spy.XHR);
-
- if (row)
- {
- setClass(row, "loading");
- spy.logRow = row;
- }
- };
-
- var finishXHR = function()
- {
- var duration = new Date().getTime() - reqStartTS;
- var success = xhrRequest.status == 200;
-
- var responseHeadersText = xhrRequest.getAllResponseHeaders();
- var responses = responseHeadersText ? responseHeadersText.split(/[\n\r]/) : [];
- var reHeader = /^(\S+):\s*(.*)/;
-
- for (var i=0, l=responses.length; i<l; i++)
- {
- var text = responses[i];
- var match = text.match(reHeader);
-
- if (match)
- {
- var name = match[1];
- var value = match[2];
-
- // update the spy mimeType property so we can detect when to show
- // custom response viewers (such as HTML, XML or JSON viewer)
- if (name == "Content-Type")
- spy.mimeType = value;
-
- /*
- if (name == "Last Modified")
- {
- if (!spy.cacheEntry)
- spy.cacheEntry = [];
-
- spy.cacheEntry.push({
- name: [name],
- value: [value]
- });
- }
- /**/
-
- spy.responseHeaders.push({
- name: [name],
- value: [value]
- });
- }
- }
-
- with({
- row: spy.logRow,
- status: xhrRequest.status == 0 ?
- // if xhrRequest.status == 0 then accessing xhrRequest.statusText
- // will cause an error, so we must handle this case (Issue 3504)
- "" : xhrRequest.status + " " + xhrRequest.statusText,
- time: duration,
- success: success
- })
- {
- setTimeout(function(){
-
- spy.responseText = xhrRequest.responseText;
-
- // update row information to avoid "ethernal spinning gif" bug in IE
- row = row || spy.logRow;
-
- // if chrome document is not loaded, there will be no row yet, so just ignore
- if (!row) return;
-
- // update the XHR representation data
- handleRequestStatus(success, status, time);
-
- },200);
- }
-
- spy.loaded = true;
- /*
- // commented because they are being updated by the updateSelfProperties() function
- self.status = xhrRequest.status;
- self.statusText = xhrRequest.statusText;
- self.responseText = xhrRequest.responseText;
- self.responseXML = xhrRequest.responseXML;
- /**/
- updateSelfProperties();
- };
-
- var handleStateChange = function()
- {
- //Firebug.Console.log(["onreadystatechange", xhrRequest.readyState, xhrRequest.readyState == 4 && xhrRequest.status]);
-
- self.readyState = xhrRequest.readyState;
-
- if (xhrRequest.readyState == 4)
- {
- finishXHR();
-
- xhrRequest.onreadystatechange = function(){};
- }
-
- //Firebug.Console.log(spy.url + ": " + xhrRequest.readyState);
-
- self.onreadystatechange();
- };
-
- // update the XHR representation data
- var handleRequestStatus = function(success, status, time)
- {
- var row = spy.logRow;
- FBL.removeClass(row, "loading");
-
- if (!success)
- FBL.setClass(row, "error");
-
- var item = FBL.$$(".spyStatus", row)[0];
- item.innerHTML = status;
-
- if (time)
- {
- var item = FBL.$$(".spyTime", row)[0];
- item.innerHTML = time + "ms";
- }
- };
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // XMLHttpRequestWrapper public properties and handlers
-
- this.readyState = 0;
-
- this.onreadystatechange = function(){};
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // XMLHttpRequestWrapper public methods
-
- this.open = function(method, url, async, user, password)
- {
- //Firebug.Console.log("xhrRequest open");
-
- updateSelfProperties();
-
- if (spy.loaded)
- spy = new XHRSpy();
-
- spy.method = method;
- spy.url = url;
- spy.async = async;
- spy.href = url;
- spy.xhrRequest = xhrRequest;
- spy.urlParams = parseURLParamsArray(url);
-
- try
- {
- // xhrRequest.open.apply may not be available in IE
- if (supportsApply)
- xhrRequest.open.apply(xhrRequest, arguments);
- else
- xhrRequest.open(method, url, async, user, password);
- }
- catch(e)
- {
- }
-
- xhrRequest.onreadystatechange = handleStateChange;
-
- };
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- this.send = function(data)
- {
- //Firebug.Console.log("xhrRequest send");
- spy.data = data;
-
- reqStartTS = new Date().getTime();
-
- updateXHRProperties();
-
- try
- {
- xhrRequest.send(data);
- }
- catch(e)
- {
- // TODO: xxxpedro XHR throws or not?
- //throw e;
- }
- finally
- {
- logXHR();
-
- if (!spy.async)
- {
- self.readyState = xhrRequest.readyState;
-
- // sometimes an error happens when calling finishXHR()
- // Issue 3422: Firebug Lite breaks Google Instant Search
- try
- {
- finishXHR();
- }
- catch(E)
- {
- }
- }
- }
- };
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- this.setRequestHeader = function(header, value)
- {
- spy.requestHeaders.push({name: [header], value: [value]});
- return xhrRequest.setRequestHeader(header, value);
- };
-
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- this.abort = function()
- {
- xhrRequest.abort();
- updateSelfProperties();
- handleRequestStatus(false, "Aborted");
- };
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- this.getResponseHeader = function(header)
- {
- return xhrRequest.getResponseHeader(header);
- };
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- this.getAllResponseHeaders = function()
- {
- return xhrRequest.getAllResponseHeaders();
- };
-
- /**/
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Clone XHR object
-
- // xhrRequest.open.apply not available in IE and will throw an error in
- // IE6 by simply reading xhrRequest.open so we must sniff it
- var supportsApply = !isIE6 &&
- xhrRequest &&
- xhrRequest.open &&
- typeof xhrRequest.open.apply != "undefined";
-
- var numberOfXHRProperties = 0;
- for (var propName in xhrRequest)
- {
- numberOfXHRProperties++;
-
- if (propName in updateSelfPropertiesIgnore)
- continue;
-
- try
- {
- var propValue = xhrRequest[propName];
-
- if (isFunction(propValue))
- {
- if (typeof self[propName] == "undefined")
- {
- this[propName] = (function(name, xhr){
-
- return supportsApply ?
- // if the browser supports apply
- function()
- {
- return xhr[name].apply(xhr, arguments);
- }
- :
- function(a,b,c,d,e)
- {
- return xhr[name](a,b,c,d,e);
- };
-
- })(propName, xhrRequest);
- }
- }
- else
- this[propName] = propValue;
- }
- catch(E)
- {
- //console.log(propName, E.message);
- }
- }
-
- // IE6 does not support for (var prop in XHR)
- var supportsXHRIterator = numberOfXHRProperties > 0;
-
- /**/
-
- return this;
-};
-
-// ************************************************************************************************
-// ActiveXObject Wrapper (IE6 only)
-
-var _ActiveXObject;
-var isIE6 = /msie 6/i.test(navigator.appVersion);
-
-if (isIE6)
-{
- _ActiveXObject = window.ActiveXObject;
-
- var xhrObjects = " MSXML2.XMLHTTP.5.0 MSXML2.XMLHTTP.4.0 MSXML2.XMLHTTP.3.0 MSXML2.XMLHTTP Microsoft.XMLHTTP ";
-
- window.ActiveXObject = function(name)
- {
- var error = null;
-
- try
- {
- var activeXObject = new _ActiveXObject(name);
- }
- catch(e)
- {
- error = e;
- }
- finally
- {
- if (!error)
- {
- if (xhrObjects.indexOf(" " + name + " ") != -1)
- return new XMLHttpRequestWrapper(activeXObject);
- else
- return activeXObject;
- }
- else
- throw error.message;
- }
- };
-}
-
-// ************************************************************************************************
-
-// Register the XMLHttpRequestWrapper for non-IE6 browsers
-if (!isIE6)
-{
- var _XMLHttpRequest = XMLHttpRequest;
- window.XMLHttpRequest = function()
- {
- return new XMLHttpRequestWrapper();
- };
-}
-
-//************************************************************************************************
-
-FBL.getNativeXHRObject = function()
-{
- var xhrObj = false;
- try
- {
- xhrObj = new _XMLHttpRequest();
- }
- catch(e)
- {
- var progid = [
- "MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0",
- "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"
- ];
-
- for ( var i=0; i < progid.length; ++i ) {
- try
- {
- xhrObj = new _ActiveXObject(progid[i]);
- }
- catch(e)
- {
- continue;
- }
- break;
- }
- }
- finally
- {
- return xhrObj;
- }
-};
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var reIgnore = /about:|javascript:|resource:|chrome:|jar:/;
-var layoutInterval = 300;
-var indentWidth = 18;
-
-var cacheSession = null;
-var contexts = new Array();
-var panelName = "net";
-var maxQueueRequests = 500;
-//var panelBar1 = $("fbPanelBar1"); // chrome not available at startup
-var activeRequests = [];
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var mimeExtensionMap =
-{
- "txt": "text/plain",
- "html": "text/html",
- "htm": "text/html",
- "xhtml": "text/html",
- "xml": "text/xml",
- "css": "text/css",
- "js": "application/x-javascript",
- "jss": "application/x-javascript",
- "jpg": "image/jpg",
- "jpeg": "image/jpeg",
- "gif": "image/gif",
- "png": "image/png",
- "bmp": "image/bmp",
- "swf": "application/x-shockwave-flash",
- "flv": "video/x-flv"
-};
-
-var fileCategories =
-{
- "undefined": 1,
- "html": 1,
- "css": 1,
- "js": 1,
- "xhr": 1,
- "image": 1,
- "flash": 1,
- "txt": 1,
- "bin": 1
-};
-
-var textFileCategories =
-{
- "txt": 1,
- "html": 1,
- "xhr": 1,
- "css": 1,
- "js": 1
-};
-
-var binaryFileCategories =
-{
- "bin": 1,
- "flash": 1
-};
-
-var mimeCategoryMap =
-{
- "text/plain": "txt",
- "application/octet-stream": "bin",
- "text/html": "html",
- "text/xml": "html",
- "text/css": "css",
- "application/x-javascript": "js",
- "text/javascript": "js",
- "application/javascript" : "js",
- "image/jpeg": "image",
- "image/jpg": "image",
- "image/gif": "image",
- "image/png": "image",
- "image/bmp": "image",
- "application/x-shockwave-flash": "flash",
- "video/x-flv": "flash"
-};
-
-var binaryCategoryMap =
-{
- "image": 1,
- "flash" : 1
-};
-
-// ************************************************************************************************
-
-/**
- * @module Represents a module object for the Net panel. This object is derived
- * from <code>Firebug.ActivableModule</code> in order to support activation (enable/disable).
- * This allows to avoid (performance) expensive features if the functionality is not necessary
- * for the user.
- */
-Firebug.NetMonitor = extend(Firebug.ActivableModule,
-{
- dispatchName: "netMonitor",
-
- clear: function(context)
- {
- // The user pressed a Clear button so, remove content of the panel...
- var panel = context.getPanel(panelName, true);
- if (panel)
- panel.clear();
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // extends Module
-
- initialize: function()
- {
- return;
-
- this.panelName = panelName;
-
- Firebug.ActivableModule.initialize.apply(this, arguments);
-
- if (Firebug.TraceModule)
- Firebug.TraceModule.addListener(this.TraceListener);
-
- // HTTP observer must be registered now (and not in monitorContext, since if a
- // page is opened in a new tab the top document request would be missed otherwise.
- NetHttpObserver.registerObserver();
- NetHttpActivityObserver.registerObserver();
-
- Firebug.Debugger.addListener(this.DebuggerListener);
- },
-
- shutdown: function()
- {
- return;
-
- prefs.removeObserver(Firebug.prefDomain, this, false);
- if (Firebug.TraceModule)
- Firebug.TraceModule.removeListener(this.TraceListener);
-
- NetHttpObserver.unregisterObserver();
- NetHttpActivityObserver.unregisterObserver();
-
- Firebug.Debugger.removeListener(this.DebuggerListener);
- }
-});
-
-
-/**
- * @domplate Represents a template that is used to reneder detailed info about a request.
- * This template is rendered when a request is expanded.
- */
-Firebug.NetMonitor.NetInfoBody = domplate(Firebug.Rep, new Firebug.Listener(),
-{
- tag:
- DIV({"class": "netInfoBody", _repObject: "$file"},
- TAG("$infoTabs", {file: "$file"}),
- TAG("$infoBodies", {file: "$file"})
- ),
-
- infoTabs:
- DIV({"class": "netInfoTabs focusRow subFocusRow", "role": "tablist"},
- A({"class": "netInfoParamsTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab",
- view: "Params",
- $collapsed: "$file|hideParams"},
- $STR("URLParameters")
- ),
- A({"class": "netInfoHeadersTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab",
- view: "Headers"},
- $STR("Headers")
- ),
- A({"class": "netInfoPostTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab",
- view: "Post",
- $collapsed: "$file|hidePost"},
- $STR("Post")
- ),
- A({"class": "netInfoPutTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab",
- view: "Put",
- $collapsed: "$file|hidePut"},
- $STR("Put")
- ),
- A({"class": "netInfoResponseTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab",
- view: "Response",
- $collapsed: "$file|hideResponse"},
- $STR("Response")
- ),
- A({"class": "netInfoCacheTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab",
- view: "Cache",
- $collapsed: "$file|hideCache"},
- $STR("Cache")
- ),
- A({"class": "netInfoHtmlTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab",
- view: "Html",
- $collapsed: "$file|hideHtml"},
- $STR("HTML")
- )
- ),
-
- infoBodies:
- DIV({"class": "netInfoBodies outerFocusRow"},
- TABLE({"class": "netInfoParamsText netInfoText netInfoParamsTable", "role": "tabpanel",
- cellpadding: 0, cellspacing: 0}, TBODY()),
- DIV({"class": "netInfoHeadersText netInfoText", "role": "tabpanel"}),
- DIV({"class": "netInfoPostText netInfoText", "role": "tabpanel"}),
- DIV({"class": "netInfoPutText netInfoText", "role": "tabpanel"}),
- PRE({"class": "netInfoResponseText netInfoText", "role": "tabpanel"}),
- DIV({"class": "netInfoCacheText netInfoText", "role": "tabpanel"},
- TABLE({"class": "netInfoCacheTable", cellpadding: 0, cellspacing: 0, "role": "presentation"},
- TBODY({"role": "list", "aria-label": $STR("Cache")})
- )
- ),
- DIV({"class": "netInfoHtmlText netInfoText", "role": "tabpanel"},
- IFRAME({"class": "netInfoHtmlPreview", "role": "document"})
- )
- ),
-
- headerDataTag:
- FOR("param", "$headers",
- TR({"role": "listitem"},
- TD({"class": "netInfoParamName", "role": "presentation"},
- TAG("$param|getNameTag", {param: "$param"})
- ),
- TD({"class": "netInfoParamValue", "role": "list", "aria-label": "$param.name"},
- FOR("line", "$param|getParamValueIterator",
- CODE({"class": "focusRow subFocusRow", "role": "listitem"}, "$line")
- )
- )
- )
- ),
-
- customTab:
- A({"class": "netInfo$tabId\\Tab netInfoTab", onclick: "$onClickTab", view: "$tabId", "role": "tab"},
- "$tabTitle"
- ),
-
- customBody:
- DIV({"class": "netInfo$tabId\\Text netInfoText", "role": "tabpanel"}),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- nameTag:
- SPAN("$param|getParamName"),
-
- nameWithTooltipTag:
- SPAN({title: "$param.name"}, "$param|getParamName"),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- getNameTag: function(param)
- {
- return (this.getParamName(param) == param.name) ? this.nameTag : this.nameWithTooltipTag;
- },
-
- getParamName: function(param)
- {
- var limit = 25;
- var name = param.name;
- if (name.length > limit)
- name = name.substr(0, limit) + "...";
- return name;
- },
-
- getParamTitle: function(param)
- {
- var limit = 25;
- var name = param.name;
- if (name.length > limit)
- return name;
- return "";
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- hideParams: function(file)
- {
- return !file.urlParams || !file.urlParams.length;
- },
-
- hidePost: function(file)
- {
- return file.method.toUpperCase() != "POST";
- },
-
- hidePut: function(file)
- {
- return file.method.toUpperCase() != "PUT";
- },
-
- hideResponse: function(file)
- {
- return false;
- //return file.category in binaryFileCategories;
- },
-
- hideCache: function(file)
- {
- return true;
- //xxxHonza: I don't see any reason why not to display the cache also info for images.
- return !file.cacheEntry; // || file.category=="image";
- },
-
- hideHtml: function(file)
- {
- return (file.mimeType != "text/html") && (file.mimeType != "application/xhtml+xml");
- },
-
- onClickTab: function(event)
- {
- this.selectTab(event.currentTarget || event.srcElement);
- },
-
- getParamValueIterator: function(param)
- {
- // TODO: xxxpedro console2
- return param.value;
-
- // This value is inserted into CODE element and so, make sure the HTML isn't escaped (1210).
- // This is why the second parameter is true.
- // The CODE (with style white-space:pre) element preserves whitespaces so they are
- // displayed the same, as they come from the server (1194).
- // In case of a long header values of post parameters the value must be wrapped (2105).
- return wrapText(param.value, true);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- appendTab: function(netInfoBox, tabId, tabTitle)
- {
- // Create new tab and body.
- var args = {tabId: tabId, tabTitle: tabTitle};
- ///this.customTab.append(args, netInfoBox.getElementsByClassName("netInfoTabs").item(0));
- ///this.customBody.append(args, netInfoBox.getElementsByClassName("netInfoBodies").item(0));
- this.customTab.append(args, $$(".netInfoTabs", netInfoBox)[0]);
- this.customBody.append(args, $$(".netInfoBodies", netInfoBox)[0]);
- },
-
- selectTabByName: function(netInfoBox, tabName)
- {
- var tab = getChildByClass(netInfoBox, "netInfoTabs", "netInfo"+tabName+"Tab");
- if (tab)
- this.selectTab(tab);
- },
-
- selectTab: function(tab)
- {
- var view = tab.getAttribute("view");
-
- var netInfoBox = getAncestorByClass(tab, "netInfoBody");
-
- var selectedTab = netInfoBox.selectedTab;
-
- if (selectedTab)
- {
- //netInfoBox.selectedText.removeAttribute("selected");
- removeClass(netInfoBox.selectedText, "netInfoTextSelected");
-
- removeClass(selectedTab, "netInfoTabSelected");
- //selectedTab.removeAttribute("selected");
- selectedTab.setAttribute("aria-selected", "false");
- }
-
- var textBodyName = "netInfo" + view + "Text";
-
- selectedTab = netInfoBox.selectedTab = tab;
-
- netInfoBox.selectedText = $$("."+textBodyName, netInfoBox)[0];
- //netInfoBox.selectedText = netInfoBox.getElementsByClassName(textBodyName).item(0);
-
- //netInfoBox.selectedText.setAttribute("selected", "true");
- setClass(netInfoBox.selectedText, "netInfoTextSelected");
-
- setClass(selectedTab, "netInfoTabSelected");
- selectedTab.setAttribute("selected", "true");
- selectedTab.setAttribute("aria-selected", "true");
-
- var file = Firebug.getRepObject(netInfoBox);
-
- //var context = Firebug.getElementPanel(netInfoBox).context;
- var context = Firebug.chrome;
-
- this.updateInfo(netInfoBox, file, context);
- },
-
- updateInfo: function(netInfoBox, file, context)
- {
- if (FBTrace.DBG_NET)
- FBTrace.sysout("net.updateInfo; file", file);
-
- if (!netInfoBox)
- {
- if (FBTrace.DBG_NET || FBTrace.DBG_ERRORS)
- FBTrace.sysout("net.updateInfo; ERROR netInfo == null " + file.href, file);
- return;
- }
-
- var tab = netInfoBox.selectedTab;
-
- if (hasClass(tab, "netInfoParamsTab"))
- {
- if (file.urlParams && !netInfoBox.urlParamsPresented)
- {
- netInfoBox.urlParamsPresented = true;
- this.insertHeaderRows(netInfoBox, file.urlParams, "Params");
- }
- }
-
- else if (hasClass(tab, "netInfoHeadersTab"))
- {
- var headersText = $$(".netInfoHeadersText", netInfoBox)[0];
- //var headersText = netInfoBox.getElementsByClassName("netInfoHeadersText").item(0);
-
- if (file.responseHeaders && !netInfoBox.responseHeadersPresented)
- {
- netInfoBox.responseHeadersPresented = true;
- NetInfoHeaders.renderHeaders(headersText, file.responseHeaders, "ResponseHeaders");
- }
-
- if (file.requestHeaders && !netInfoBox.requestHeadersPresented)
- {
- netInfoBox.requestHeadersPresented = true;
- NetInfoHeaders.renderHeaders(headersText, file.requestHeaders, "RequestHeaders");
- }
- }
-
- else if (hasClass(tab, "netInfoPostTab"))
- {
- if (!netInfoBox.postPresented)
- {
- netInfoBox.postPresented = true;
- //var postText = netInfoBox.getElementsByClassName("netInfoPostText").item(0);
- var postText = $$(".netInfoPostText", netInfoBox)[0];
- NetInfoPostData.render(context, postText, file);
- }
- }
-
- else if (hasClass(tab, "netInfoPutTab"))
- {
- if (!netInfoBox.putPresented)
- {
- netInfoBox.putPresented = true;
- //var putText = netInfoBox.getElementsByClassName("netInfoPutText").item(0);
- var putText = $$(".netInfoPutText", netInfoBox)[0];
- NetInfoPostData.render(context, putText, file);
- }
- }
-
- else if (hasClass(tab, "netInfoResponseTab") && file.loaded && !netInfoBox.responsePresented)
- {
- ///var responseTextBox = netInfoBox.getElementsByClassName("netInfoResponseText").item(0);
- var responseTextBox = $$(".netInfoResponseText", netInfoBox)[0];
- if (file.category == "image")
- {
- netInfoBox.responsePresented = true;
-
- var responseImage = netInfoBox.ownerDocument.createElement("img");
- responseImage.src = file.href;
-
- clearNode(responseTextBox);
- responseTextBox.appendChild(responseImage, responseTextBox);
- }
- else ///if (!(binaryCategoryMap.hasOwnProperty(file.category)))
- {
- this.setResponseText(file, netInfoBox, responseTextBox, context);
- }
- }
-
- else if (hasClass(tab, "netInfoCacheTab") && file.loaded && !netInfoBox.cachePresented)
- {
- var responseTextBox = netInfoBox.getElementsByClassName("netInfoCacheText").item(0);
- if (file.cacheEntry) {
- netInfoBox.cachePresented = true;
- this.insertHeaderRows(netInfoBox, file.cacheEntry, "Cache");
- }
- }
-
- else if (hasClass(tab, "netInfoHtmlTab") && file.loaded && !netInfoBox.htmlPresented)
- {
- netInfoBox.htmlPresented = true;
-
- var text = Utils.getResponseText(file, context);
-
- ///var iframe = netInfoBox.getElementsByClassName("netInfoHtmlPreview").item(0);
- var iframe = $$(".netInfoHtmlPreview", netInfoBox)[0];
-
- ///iframe.contentWindow.document.body.innerHTML = text;
-
- // TODO: xxxpedro net - remove scripts
- var reScript = /<script(.|\s)*?\/script>/gi;
-
- text = text.replace(reScript, "");
-
- iframe.contentWindow.document.write(text);
- iframe.contentWindow.document.close();
- }
-
- // Notify listeners about update so, content of custom tabs can be updated.
- dispatch(NetInfoBody.fbListeners, "updateTabBody", [netInfoBox, file, context]);
- },
-
- setResponseText: function(file, netInfoBox, responseTextBox, context)
- {
- //**********************************************
- //**********************************************
- //**********************************************
- netInfoBox.responsePresented = true;
- // line breaks somehow are different in IE
- // make this only once in the initialization? we don't have net panels and modules yet.
- if (isIE)
- responseTextBox.style.whiteSpace = "nowrap";
-
- responseTextBox[
- typeof responseTextBox.textContent != "undefined" ?
- "textContent" :
- "innerText"
- ] = file.responseText;
-
- return;
- //**********************************************
- //**********************************************
- //**********************************************
-
- // Get response text and make sure it doesn't exceed the max limit.
- var text = Utils.getResponseText(file, context);
- var limit = Firebug.netDisplayedResponseLimit + 15;
- var limitReached = text ? (text.length > limit) : false;
- if (limitReached)
- text = text.substr(0, limit) + "...";
-
- // Insert the response into the UI.
- if (text)
- insertWrappedText(text, responseTextBox);
- else
- insertWrappedText("", responseTextBox);
-
- // Append a message informing the user that the response isn't fully displayed.
- if (limitReached)
- {
- var object = {
- text: $STR("net.responseSizeLimitMessage"),
- onClickLink: function() {
- var panel = context.getPanel("net", true);
- panel.openResponseInTab(file);
- }
- };
- Firebug.NetMonitor.ResponseSizeLimit.append(object, responseTextBox);
- }
-
- netInfoBox.responsePresented = true;
-
- if (FBTrace.DBG_NET)
- FBTrace.sysout("net.setResponseText; response text updated");
- },
-
- insertHeaderRows: function(netInfoBox, headers, tableName, rowName)
- {
- if (!headers.length)
- return;
-
- var headersTable = $$(".netInfo"+tableName+"Table", netInfoBox)[0];
- //var headersTable = netInfoBox.getElementsByClassName("netInfo"+tableName+"Table").item(0);
- var tbody = getChildByClass(headersTable, "netInfo" + rowName + "Body");
- if (!tbody)
- tbody = headersTable.firstChild;
- var titleRow = getChildByClass(tbody, "netInfo" + rowName + "Title");
-
- this.headerDataTag.insertRows({headers: headers}, titleRow ? titleRow : tbody);
- removeClass(titleRow, "collapsed");
- }
-});
-
-var NetInfoBody = Firebug.NetMonitor.NetInfoBody;
-
-// ************************************************************************************************
-
-/**
- * @domplate Used within the Net panel to display raw source of request and response headers
- * as well as pretty-formatted summary of these headers.
- */
-Firebug.NetMonitor.NetInfoHeaders = domplate(Firebug.Rep, //new Firebug.Listener(),
-{
- tag:
- DIV({"class": "netInfoHeadersTable", "role": "tabpanel"},
- DIV({"class": "netInfoHeadersGroup netInfoResponseHeadersTitle"},
- SPAN($STR("ResponseHeaders")),
- SPAN({"class": "netHeadersViewSource response collapsed", onclick: "$onViewSource",
- _sourceDisplayed: false, _rowName: "ResponseHeaders"},
- $STR("net.headers.view source")
- )
- ),
- TABLE({cellpadding: 0, cellspacing: 0},
- TBODY({"class": "netInfoResponseHeadersBody", "role": "list",
- "aria-label": $STR("ResponseHeaders")})
- ),
- DIV({"class": "netInfoHeadersGroup netInfoRequestHeadersTitle"},
- SPAN($STR("RequestHeaders")),
- SPAN({"class": "netHeadersViewSource request collapsed", onclick: "$onViewSource",
- _sourceDisplayed: false, _rowName: "RequestHeaders"},
- $STR("net.headers.view source")
- )
- ),
- TABLE({cellpadding: 0, cellspacing: 0},
- TBODY({"class": "netInfoRequestHeadersBody", "role": "list",
- "aria-label": $STR("RequestHeaders")})
- )
- ),
-
- sourceTag:
- TR({"role": "presentation"},
- TD({colspan: 2, "role": "presentation"},
- PRE({"class": "source"})
- )
- ),
-
- onViewSource: function(event)
- {
- var target = event.target;
- var requestHeaders = (target.rowName == "RequestHeaders");
-
- var netInfoBox = getAncestorByClass(target, "netInfoBody");
- var file = netInfoBox.repObject;
-
- if (target.sourceDisplayed)
- {
- var headers = requestHeaders ? file.requestHeaders : file.responseHeaders;
- this.insertHeaderRows(netInfoBox, headers, target.rowName);
- target.innerHTML = $STR("net.headers.view source");
- }
- else
- {
- var source = requestHeaders ? file.requestHeadersText : file.responseHeadersText;
- this.insertSource(netInfoBox, source, target.rowName);
- target.innerHTML = $STR("net.headers.pretty print");
- }
-
- target.sourceDisplayed = !target.sourceDisplayed;
-
- cancelEvent(event);
- },
-
- insertSource: function(netInfoBox, source, rowName)
- {
- // This breaks copy to clipboard.
- //if (source)
- // source = source.replace(/\r\n/gm, "<span style='color:lightgray'>\\r\\n</span>\r\n");
-
- ///var tbody = netInfoBox.getElementsByClassName("netInfo" + rowName + "Body").item(0);
- var tbody = $$(".netInfo" + rowName + "Body", netInfoBox)[0];
- var node = this.sourceTag.replace({}, tbody);
- ///var sourceNode = node.getElementsByClassName("source").item(0);
- var sourceNode = $$(".source", node)[0];
- sourceNode.innerHTML = source;
- },
-
- insertHeaderRows: function(netInfoBox, headers, rowName)
- {
- var headersTable = $$(".netInfoHeadersTable", netInfoBox)[0];
- var tbody = $$(".netInfo" + rowName + "Body", headersTable)[0];
-
- //var headersTable = netInfoBox.getElementsByClassName("netInfoHeadersTable").item(0);
- //var tbody = headersTable.getElementsByClassName("netInfo" + rowName + "Body").item(0);
-
- clearNode(tbody);
-
- if (!headers.length)
- return;
-
- NetInfoBody.headerDataTag.insertRows({headers: headers}, tbody);
-
- var titleRow = getChildByClass(headersTable, "netInfo" + rowName + "Title");
- removeClass(titleRow, "collapsed");
- },
-
- init: function(parent)
- {
- var rootNode = this.tag.append({}, parent);
-
- var netInfoBox = getAncestorByClass(parent, "netInfoBody");
- var file = netInfoBox.repObject;
-
- var viewSource;
-
- viewSource = $$(".request", rootNode)[0];
- //viewSource = rootNode.getElementsByClassName("netHeadersViewSource request").item(0);
- if (file.requestHeadersText)
- removeClass(viewSource, "collapsed");
-
- viewSource = $$(".response", rootNode)[0];
- //viewSource = rootNode.getElementsByClassName("netHeadersViewSource response").item(0);
- if (file.responseHeadersText)
- removeClass(viewSource, "collapsed");
- },
-
- renderHeaders: function(parent, headers, rowName)
- {
- if (!parent.firstChild)
- this.init(parent);
-
- this.insertHeaderRows(parent, headers, rowName);
- }
-});
-
-var NetInfoHeaders = Firebug.NetMonitor.NetInfoHeaders;
-
-// ************************************************************************************************
-
-/**
- * @domplate Represents posted data within request info (the info, which is visible when
- * a request entry is expanded. This template renders content of the Post tab.
- */
-Firebug.NetMonitor.NetInfoPostData = domplate(Firebug.Rep, /*new Firebug.Listener(),*/
-{
- // application/x-www-form-urlencoded
- paramsTable:
- TABLE({"class": "netInfoPostParamsTable", cellpadding: 0, cellspacing: 0, "role": "presentation"},
- TBODY({"role": "list", "aria-label": $STR("net.label.Parameters")},
- TR({"class": "netInfoPostParamsTitle", "role": "presentation"},
- TD({colspan: 3, "role": "presentation"},
- DIV({"class": "netInfoPostParams"},
- $STR("net.label.Parameters"),
- SPAN({"class": "netInfoPostContentType"},
- "application/x-www-form-urlencoded"
- )
- )
- )
- )
- )
- ),
-
- // multipart/form-data
- partsTable:
- TABLE({"class": "netInfoPostPartsTable", cellpadding: 0, cellspacing: 0, "role": "presentation"},
- TBODY({"role": "list", "aria-label": $STR("net.label.Parts")},
- TR({"class": "netInfoPostPartsTitle", "role": "presentation"},
- TD({colspan: 2, "role":"presentation" },
- DIV({"class": "netInfoPostParams"},
- $STR("net.label.Parts"),
- SPAN({"class": "netInfoPostContentType"},
- "multipart/form-data"
- )
- )
- )
- )
- )
- ),
-
- // application/json
- jsonTable:
- TABLE({"class": "netInfoPostJSONTable", cellpadding: 0, cellspacing: 0, "role": "presentation"},
- ///TBODY({"role": "list", "aria-label": $STR("jsonviewer.tab.JSON")},
- TBODY({"role": "list", "aria-label": $STR("JSON")},
- TR({"class": "netInfoPostJSONTitle", "role": "presentation"},
- TD({"role": "presentation" },
- DIV({"class": "netInfoPostParams"},
- ///$STR("jsonviewer.tab.JSON")
- $STR("JSON")
- )
- )
- ),
- TR(
- TD({"class": "netInfoPostJSONBody"})
- )
- )
- ),
-
- // application/xml
- xmlTable:
- TABLE({"class": "netInfoPostXMLTable", cellpadding: 0, cellspacing: 0, "role": "presentation"},
- TBODY({"role": "list", "aria-label": $STR("xmlviewer.tab.XML")},
- TR({"class": "netInfoPostXMLTitle", "role": "presentation"},
- TD({"role": "presentation" },
- DIV({"class": "netInfoPostParams"},
- $STR("xmlviewer.tab.XML")
- )
- )
- ),
- TR(
- TD({"class": "netInfoPostXMLBody"})
- )
- )
- ),
-
- sourceTable:
- TABLE({"class": "netInfoPostSourceTable", cellpadding: 0, cellspacing: 0, "role": "presentation"},
- TBODY({"role": "list", "aria-label": $STR("net.label.Source")},
- TR({"class": "netInfoPostSourceTitle", "role": "presentation"},
- TD({colspan: 2, "role": "presentation"},
- DIV({"class": "netInfoPostSource"},
- $STR("net.label.Source")
- )
- )
- )
- )
- ),
-
- sourceBodyTag:
- TR({"role": "presentation"},
- TD({colspan: 2, "role": "presentation"},
- FOR("line", "$param|getParamValueIterator",
- CODE({"class":"focusRow subFocusRow" , "role": "listitem"},"$line")
- )
- )
- ),
-
- getParamValueIterator: function(param)
- {
- return NetInfoBody.getParamValueIterator(param);
- },
-
- render: function(context, parentNode, file)
- {
- //debugger;
- var spy = getAncestorByClass(parentNode, "spyHead");
- var spyObject = spy.repObject;
- var data = spyObject.data;
-
- ///var contentType = Utils.findHeader(file.requestHeaders, "content-type");
- var contentType = file.mimeType;
-
- ///var text = Utils.getPostText(file, context, true);
- ///if (text == undefined)
- /// return;
-
- ///if (Utils.isURLEncodedRequest(file, context))
- // fake Utils.isURLEncodedRequest identification
- if (contentType && contentType == "application/x-www-form-urlencoded" ||
- data && data.indexOf("=") != -1)
- {
- ///var lines = text.split("\n");
- ///var params = parseURLEncodedText(lines[lines.length-1]);
- var params = parseURLEncodedTextArray(data);
- if (params)
- this.insertParameters(parentNode, params);
- }
-
- ///if (Utils.isMultiPartRequest(file, context))
- ///{
- /// var data = this.parseMultiPartText(file, context);
- /// if (data)
- /// this.insertParts(parentNode, data);
- ///}
-
- // moved to the top
- ///var contentType = Utils.findHeader(file.requestHeaders, "content-type");
-
- ///if (Firebug.JSONViewerModel.isJSON(contentType))
- var jsonData = {
- responseText: data
- };
-
- if (Firebug.JSONViewerModel.isJSON(contentType, data))
- ///this.insertJSON(parentNode, file, context);
- this.insertJSON(parentNode, jsonData, context);
-
- ///if (Firebug.XMLViewerModel.isXML(contentType))
- /// this.insertXML(parentNode, file, context);
-
- ///var postText = Utils.getPostText(file, context);
- ///postText = Utils.formatPostText(postText);
- var postText = data;
- if (postText)
- this.insertSource(parentNode, postText);
- },
-
- insertParameters: function(parentNode, params)
- {
- if (!params || !params.length)
- return;
-
- var paramTable = this.paramsTable.append({object:{}}, parentNode);
- var row = $$(".netInfoPostParamsTitle", paramTable)[0];
- //var paramTable = this.paramsTable.append(null, parentNode);
- //var row = paramTable.getElementsByClassName("netInfoPostParamsTitle").item(0);
-
- var tbody = paramTable.getElementsByTagName("tbody")[0];
-
- NetInfoBody.headerDataTag.insertRows({headers: params}, row);
- },
-
- insertParts: function(parentNode, data)
- {
- if (!data.params || !data.params.length)
- return;
-
- var partsTable = this.partsTable.append({object:{}}, parentNode);
- var row = $$(".netInfoPostPartsTitle", paramTable)[0];
- //var partsTable = this.partsTable.append(null, parentNode);
- //var row = partsTable.getElementsByClassName("netInfoPostPartsTitle").item(0);
-
- NetInfoBody.headerDataTag.insertRows({headers: data.params}, row);
- },
-
- insertJSON: function(parentNode, file, context)
- {
- ///var text = Utils.getPostText(file, context);
- var text = file.responseText;
- ///var data = parseJSONString(text, "http://" + file.request.originalURI.host);
- var data = parseJSONString(text);
- if (!data)
- return;
-
- ///var jsonTable = this.jsonTable.append(null, parentNode);
- var jsonTable = this.jsonTable.append({}, parentNode);
- ///var jsonBody = jsonTable.getElementsByClassName("netInfoPostJSONBody").item(0);
- var jsonBody = $$(".netInfoPostJSONBody", jsonTable)[0];
-
- if (!this.toggles)
- this.toggles = {};
-
- Firebug.DOMPanel.DirTable.tag.replace(
- {object: data, toggles: this.toggles}, jsonBody);
- },
-
- insertXML: function(parentNode, file, context)
- {
- var text = Utils.getPostText(file, context);
-
- var jsonTable = this.xmlTable.append(null, parentNode);
- ///var jsonBody = jsonTable.getElementsByClassName("netInfoPostXMLBody").item(0);
- var jsonBody = $$(".netInfoPostXMLBody", jsonTable)[0];
-
- Firebug.XMLViewerModel.insertXML(jsonBody, text);
- },
-
- insertSource: function(parentNode, text)
- {
- var sourceTable = this.sourceTable.append({object:{}}, parentNode);
- var row = $$(".netInfoPostSourceTitle", sourceTable)[0];
- //var sourceTable = this.sourceTable.append(null, parentNode);
- //var row = sourceTable.getElementsByClassName("netInfoPostSourceTitle").item(0);
-
- var param = {value: [text]};
- this.sourceBodyTag.insertRows({param: param}, row);
- },
-
- parseMultiPartText: function(file, context)
- {
- var text = Utils.getPostText(file, context);
- if (text == undefined)
- return null;
-
- FBTrace.sysout("net.parseMultiPartText; boundary: ", text);
-
- var boundary = text.match(/\s*boundary=\s*(.*)/)[1];
-
- var divider = "\r\n\r\n";
- var bodyStart = text.indexOf(divider);
- var body = text.substr(bodyStart + divider.length);
-
- var postData = {};
- postData.mimeType = "multipart/form-data";
- postData.params = [];
-
- var parts = body.split("--" + boundary);
- for (var i=0; i<parts.length; i++)
- {
- var part = parts[i].split(divider);
- if (part.length != 2)
- continue;
-
- var m = part[0].match(/\s*name=\"(.*)\"(;|$)/);
- postData.params.push({
- name: (m && m.length > 1) ? m[1] : "",
- value: trim(part[1])
- });
- }
-
- return postData;
- }
-});
-
-var NetInfoPostData = Firebug.NetMonitor.NetInfoPostData;
-
-// ************************************************************************************************
-
-
-// TODO: xxxpedro net i18n
-var $STRP = function(a){return a;};
-
-Firebug.NetMonitor.NetLimit = domplate(Firebug.Rep,
-{
- collapsed: true,
-
- tableTag:
- DIV(
- TABLE({width: "100%", cellpadding: 0, cellspacing: 0},
- TBODY()
- )
- ),
-
- limitTag:
- TR({"class": "netRow netLimitRow", $collapsed: "$isCollapsed"},
- TD({"class": "netCol netLimitCol", colspan: 6},
- TABLE({cellpadding: 0, cellspacing: 0},
- TBODY(
- TR(
- TD(
- SPAN({"class": "netLimitLabel"},
- $STRP("plural.Limit_Exceeded", [0])
- )
- ),
- TD({style: "width:100%"}),
- TD(
- BUTTON({"class": "netLimitButton", title: "$limitPrefsTitle",
- onclick: "$onPreferences"},
- $STR("LimitPrefs")
- )
- ),
- TD("&nbsp;")
- )
- )
- )
- )
- ),
-
- isCollapsed: function()
- {
- return this.collapsed;
- },
-
- onPreferences: function(event)
- {
- openNewTab("about:config");
- },
-
- updateCounter: function(row)
- {
- removeClass(row, "collapsed");
-
- // Update info within the limit row.
- var limitLabel = row.getElementsByClassName("netLimitLabel").item(0);
- limitLabel.firstChild.nodeValue = $STRP("plural.Limit_Exceeded", [row.limitInfo.totalCount]);
- },
-
- createTable: function(parent, limitInfo)
- {
- var table = this.tableTag.replace({}, parent);
- var row = this.createRow(table.firstChild.firstChild, limitInfo);
- return [table, row];
- },
-
- createRow: function(parent, limitInfo)
- {
- var row = this.limitTag.insertRows(limitInfo, parent, this)[0];
- row.limitInfo = limitInfo;
- return row;
- },
-
- // nsIPrefObserver
- observe: function(subject, topic, data)
- {
- // We're observing preferences only.
- if (topic != "nsPref:changed")
- return;
-
- if (data.indexOf("net.logLimit") != -1)
- this.updateMaxLimit();
- },
-
- updateMaxLimit: function()
- {
- var value = Firebug.getPref(Firebug.prefDomain, "net.logLimit");
- maxQueueRequests = value ? value : maxQueueRequests;
- }
-});
-
-var NetLimit = Firebug.NetMonitor.NetLimit;
-
-// ************************************************************************************************
-
-Firebug.NetMonitor.ResponseSizeLimit = domplate(Firebug.Rep,
-{
- tag:
- DIV({"class": "netInfoResponseSizeLimit"},
- SPAN("$object.beforeLink"),
- A({"class": "objectLink", onclick: "$onClickLink"},
- "$object.linkText"
- ),
- SPAN("$object.afterLink")
- ),
-
- reLink: /^(.*)<a>(.*)<\/a>(.*$)/,
- append: function(obj, parent)
- {
- var m = obj.text.match(this.reLink);
- return this.tag.append({onClickLink: obj.onClickLink,
- object: {
- beforeLink: m[1],
- linkText: m[2],
- afterLink: m[3]
- }}, parent, this);
- }
-});
-
-// ************************************************************************************************
-// ************************************************************************************************
-
-Firebug.NetMonitor.Utils =
-{
- findHeader: function(headers, name)
- {
- if (!headers)
- return null;
-
- name = name.toLowerCase();
- for (var i = 0; i < headers.length; ++i)
- {
- var headerName = headers[i].name.toLowerCase();
- if (headerName == name)
- return headers[i].value;
- }
- },
-
- formatPostText: function(text)
- {
- if (text instanceof XMLDocument)
- return getElementXML(text.documentElement);
- else
- return text;
- },
-
- getPostText: function(file, context, noLimit)
- {
- if (!file.postText)
- {
- file.postText = readPostTextFromRequest(file.request, context);
-
- if (!file.postText && context)
- file.postText = readPostTextFromPage(file.href, context);
- }
-
- if (!file.postText)
- return file.postText;
-
- var limit = Firebug.netDisplayedPostBodyLimit;
- if (file.postText.length > limit && !noLimit)
- {
- return cropString(file.postText, limit,
- "\n\n... " + $STR("net.postDataSizeLimitMessage") + " ...\n\n");
- }
-
- return file.postText;
- },
-
- getResponseText: function(file, context)
- {
- // The response can be also empty string so, check agains "undefined".
- return (typeof(file.responseText) != "undefined")? file.responseText :
- context.sourceCache.loadText(file.href, file.method, file);
- },
-
- isURLEncodedRequest: function(file, context)
- {
- var text = Utils.getPostText(file, context);
- if (text && text.toLowerCase().indexOf("content-type: application/x-www-form-urlencoded") == 0)
- return true;
-
- // The header value doesn't have to be always exactly "application/x-www-form-urlencoded",
- // there can be even charset specified. So, use indexOf rather than just "==".
- var headerValue = Utils.findHeader(file.requestHeaders, "content-type");
- if (headerValue && headerValue.indexOf("application/x-www-form-urlencoded") == 0)
- return true;
-
- return false;
- },
-
- isMultiPartRequest: function(file, context)
- {
- var text = Utils.getPostText(file, context);
- if (text && text.toLowerCase().indexOf("content-type: multipart/form-data") == 0)
- return true;
- return false;
- },
-
- getMimeType: function(mimeType, uri)
- {
- if (!mimeType || !(mimeCategoryMap.hasOwnProperty(mimeType)))
- {
- var ext = getFileExtension(uri);
- if (!ext)
- return mimeType;
- else
- {
- var extMimeType = mimeExtensionMap[ext.toLowerCase()];
- return extMimeType ? extMimeType : mimeType;
- }
- }
- else
- return mimeType;
- },
-
- getDateFromSeconds: function(s)
- {
- var d = new Date();
- d.setTime(s*1000);
- return d;
- },
-
- getHttpHeaders: function(request, file)
- {
- try
- {
- var http = QI(request, Ci.nsIHttpChannel);
- file.status = request.responseStatus;
-
- // xxxHonza: is there any problem to do this in requestedFile method?
- file.method = http.requestMethod;
- file.urlParams = parseURLParams(file.href);
- file.mimeType = Utils.getMimeType(request.contentType, request.name);
-
- if (!file.responseHeaders && Firebug.collectHttpHeaders)
- {
- var requestHeaders = [], responseHeaders = [];
-
- http.visitRequestHeaders({
- visitHeader: function(name, value)
- {
- requestHeaders.push({name: name, value: value});
- }
- });
- http.visitResponseHeaders({
- visitHeader: function(name, value)
- {
- responseHeaders.push({name: name, value: value});
- }
- });
-
- file.requestHeaders = requestHeaders;
- file.responseHeaders = responseHeaders;
- }
- }
- catch (exc)
- {
- // An exception can be throwed e.g. when the request is aborted and
- // request.responseStatus is accessed.
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("net.getHttpHeaders FAILS " + file.href, exc);
- }
- },
-
- isXHR: function(request)
- {
- try
- {
- var callbacks = request.notificationCallbacks;
- var xhrRequest = callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null;
- if (FBTrace.DBG_NET)
- FBTrace.sysout("net.isXHR; " + (xhrRequest != null) + ", " + safeGetName(request));
-
- return (xhrRequest != null);
- }
- catch (exc)
- {
- }
-
- return false;
- },
-
- getFileCategory: function(file)
- {
- if (file.category)
- {
- if (FBTrace.DBG_NET)
- FBTrace.sysout("net.getFileCategory; current: " + file.category + " for: " + file.href, file);
- return file.category;
- }
-
- if (file.isXHR)
- {
- if (FBTrace.DBG_NET)
- FBTrace.sysout("net.getFileCategory; XHR for: " + file.href, file);
- return file.category = "xhr";
- }
-
- if (!file.mimeType)
- {
- var ext = getFileExtension(file.href);
- if (ext)
- file.mimeType = mimeExtensionMap[ext.toLowerCase()];
- }
-
- /*if (FBTrace.DBG_NET)
- FBTrace.sysout("net.getFileCategory; " + mimeCategoryMap[file.mimeType] +
- ", mimeType: " + file.mimeType + " for: " + file.href, file);*/
-
- if (!file.mimeType)
- return "";
-
- // Solve cases when charset is also specified, eg "text/html; charset=UTF-8".
- var mimeType = file.mimeType;
- if (mimeType)
- mimeType = mimeType.split(";")[0];
-
- return (file.category = mimeCategoryMap[mimeType]);
- }
-};
-
-var Utils = Firebug.NetMonitor.Utils;
-
-// ************************************************************************************************
-
-//Firebug.registerRep(Firebug.NetMonitor.NetRequestTable);
-//Firebug.registerActivableModule(Firebug.NetMonitor);
-//Firebug.registerPanel(NetPanel);
-
-Firebug.registerModule(Firebug.NetMonitor);
-//Firebug.registerRep(Firebug.NetMonitor.BreakpointRep);
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-
-// ************************************************************************************************
-// Constants
-
-//const Cc = Components.classes;
-//const Ci = Components.interfaces;
-
-// List of contexts with XHR spy attached.
-var contexts = [];
-
-// ************************************************************************************************
-// Spy Module
-
-/**
- * @module Represents a XHR Spy module. The main purpose of the XHR Spy feature is to monitor
- * XHR activity of the current page and create appropriate log into the Console panel.
- * This feature can be controlled by an option <i>Show XMLHttpRequests</i> (from within the
- * console panel).
- *
- * The module is responsible for attaching/detaching a HTTP Observers when Firebug is
- * activated/deactivated for a site.
- */
-Firebug.Spy = extend(Firebug.Module,
-/** @lends Firebug.Spy */
-{
- dispatchName: "spy",
-
- initialize: function()
- {
- if (Firebug.TraceModule)
- Firebug.TraceModule.addListener(this.TraceListener);
-
- Firebug.Module.initialize.apply(this, arguments);
- },
-
- shutdown: function()
- {
- Firebug.Module.shutdown.apply(this, arguments);
-
- if (Firebug.TraceModule)
- Firebug.TraceModule.removeListener(this.TraceListener);
- },
-
- initContext: function(context)
- {
- context.spies = [];
-
- if (Firebug.showXMLHttpRequests && Firebug.Console.isAlwaysEnabled())
- this.attachObserver(context, context.window);
-
- if (FBTrace.DBG_SPY)
- FBTrace.sysout("spy.initContext " + contexts.length + " ", context.getName());
- },
-
- destroyContext: function(context)
- {
- // For any spies that are in progress, remove our listeners so that they don't leak
- this.detachObserver(context, null);
-
- if (FBTrace.DBG_SPY && context.spies.length)
- FBTrace.sysout("spy.destroyContext; ERROR There are leaking Spies ("
- + context.spies.length + ") " + context.getName());
-
- delete context.spies;
-
- if (FBTrace.DBG_SPY)
- FBTrace.sysout("spy.destroyContext " + contexts.length + " ", context.getName());
- },
-
- watchWindow: function(context, win)
- {
- if (Firebug.showXMLHttpRequests && Firebug.Console.isAlwaysEnabled())
- this.attachObserver(context, win);
- },
-
- unwatchWindow: function(context, win)
- {
- try
- {
- // This make sure that the existing context is properly removed from "contexts" array.
- this.detachObserver(context, win);
- }
- catch (ex)
- {
- // Get exceptions here sometimes, so let's just ignore them
- // since the window is going away anyhow
- ERROR(ex);
- }
- },
-
- updateOption: function(name, value)
- {
- // XXXjjb Honza, if Console.isEnabled(context) false, then this can't be called,
- // but somehow seems not correct
- if (name == "showXMLHttpRequests")
- {
- var tach = value ? this.attachObserver : this.detachObserver;
- for (var i = 0; i < TabWatcher.contexts.length; ++i)
- {
- var context = TabWatcher.contexts[i];
- iterateWindows(context.window, function(win)
- {
- tach.apply(this, [context, win]);
- });
- }
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Attaching Spy to XHR requests.
-
- /**
- * Returns false if Spy should not be attached to XHRs executed by the specified window.
- */
- skipSpy: function(win)
- {
- if (!win)
- return true;
-
- // Don't attach spy to chrome.
- var uri = safeGetWindowLocation(win);
- if (uri && (uri.indexOf("about:") == 0 || uri.indexOf("chrome:") == 0))
- return true;
- },
-
- attachObserver: function(context, win)
- {
- if (Firebug.Spy.skipSpy(win))
- return;
-
- for (var i=0; i<contexts.length; ++i)
- {
- if ((contexts[i].context == context) && (contexts[i].win == win))
- return;
- }
-
- // Register HTTP observers only once.
- if (contexts.length == 0)
- {
- httpObserver.addObserver(SpyHttpObserver, "firebug-http-event", false);
- SpyHttpActivityObserver.registerObserver();
- }
-
- contexts.push({context: context, win: win});
-
- if (FBTrace.DBG_SPY)
- FBTrace.sysout("spy.attachObserver (HTTP) " + contexts.length + " ", context.getName());
- },
-
- detachObserver: function(context, win)
- {
- for (var i=0; i<contexts.length; ++i)
- {
- if (contexts[i].context == context)
- {
- if (win && (contexts[i].win != win))
- continue;
-
- contexts.splice(i, 1);
-
- // If no context is using spy, remvove the (only one) HTTP observer.
- if (contexts.length == 0)
- {
- httpObserver.removeObserver(SpyHttpObserver, "firebug-http-event");
- SpyHttpActivityObserver.unregisterObserver();
- }
-
- if (FBTrace.DBG_SPY)
- FBTrace.sysout("spy.detachObserver (HTTP) " + contexts.length + " ",
- context.getName());
- return;
- }
- }
- },
-
- /**
- * Return XHR object that is associated with specified request <i>nsIHttpChannel</i>.
- * Returns null if the request doesn't represent XHR.
- */
- getXHR: function(request)
- {
- // Does also query-interface for nsIHttpChannel.
- if (!(request instanceof Ci.nsIHttpChannel))
- return null;
-
- try
- {
- var callbacks = request.notificationCallbacks;
- return (callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null);
- }
- catch (exc)
- {
- if (exc.name == "NS_NOINTERFACE")
- {
- if (FBTrace.DBG_SPY)
- FBTrace.sysout("spy.getXHR; Request is not nsIXMLHttpRequest: " +
- safeGetRequestName(request));
- }
- }
-
- return null;
- }
-});
-
-
-
-
-
-// ************************************************************************************************
-
-/*
-function getSpyForXHR(request, xhrRequest, context, noCreate)
-{
- var spy = null;
-
- // Iterate all existing spy objects in this context and look for one that is
- // already created for this request.
- var length = context.spies.length;
- for (var i=0; i<length; i++)
- {
- spy = context.spies[i];
- if (spy.request == request)
- return spy;
- }
-
- if (noCreate)
- return null;
-
- spy = new Firebug.Spy.XMLHttpRequestSpy(request, xhrRequest, context);
- context.spies.push(spy);
-
- var name = request.URI.asciiSpec;
- var origName = request.originalURI.asciiSpec;
-
- // Attach spy only to the original request. Notice that there can be more network requests
- // made by the same XHR if redirects are involved.
- if (name == origName)
- spy.attach();
-
- if (FBTrace.DBG_SPY)
- FBTrace.sysout("spy.getSpyForXHR; New spy object created (" +
- (name == origName ? "new XHR" : "redirected XHR") + ") for: " + name, spy);
-
- return spy;
-}
-/**/
-
-// ************************************************************************************************
-
-/**
- * @class This class represents a Spy object that is attached to XHR. This object
- * registers various listeners into the XHR in order to monitor various events fired
- * during the request process (onLoad, onAbort, etc.)
- */
-/*
-Firebug.Spy.XMLHttpRequestSpy = function(request, xhrRequest, context)
-{
- this.request = request;
- this.xhrRequest = xhrRequest;
- this.context = context;
- this.responseText = "";
-
- // For compatibility with the Net templates.
- this.isXHR = true;
-
- // Support for activity-observer
- this.transactionStarted = false;
- this.transactionClosed = false;
-};
-/**/
-
-//Firebug.Spy.XMLHttpRequestSpy.prototype =
-/** @lends Firebug.Spy.XMLHttpRequestSpy */
-/*
-{
- attach: function()
- {
- var spy = this;
- this.onReadyStateChange = function(event) { onHTTPSpyReadyStateChange(spy, event); };
- this.onLoad = function() { onHTTPSpyLoad(spy); };
- this.onError = function() { onHTTPSpyError(spy); };
- this.onAbort = function() { onHTTPSpyAbort(spy); };
-
- // xxxHonza: #502959 is still failing on Fx 3.5
- // Use activity distributor to identify 3.6
- if (SpyHttpActivityObserver.getActivityDistributor())
- {
- this.onreadystatechange = this.xhrRequest.onreadystatechange;
- this.xhrRequest.onreadystatechange = this.onReadyStateChange;
- }
-
- this.xhrRequest.addEventListener("load", this.onLoad, false);
- this.xhrRequest.addEventListener("error", this.onError, false);
- this.xhrRequest.addEventListener("abort", this.onAbort, false);
-
- // xxxHonza: should be removed from FB 3.6
- if (!SpyHttpActivityObserver.getActivityDistributor())
- this.context.sourceCache.addListener(this);
- },
-
- detach: function()
- {
- // Bubble out if already detached.
- if (!this.onLoad)
- return;
-
- // If the activity distributor is available, let's detach it when the XHR
- // transaction is closed. Since, in case of multipart XHRs the onLoad method
- // (readyState == 4) can be called mutliple times.
- // Keep in mind:
- // 1) It can happen that that the TRANSACTION_CLOSE event comes before
- // the onLoad (if the XHR is made as part of the page load) so, detach if
- // it's already closed.
- // 2) In case of immediate cache responses, the transaction doesn't have to
- // be started at all (or the activity observer is no available in Firefox 3.5).
- // So, also detach in this case.
- if (this.transactionStarted && !this.transactionClosed)
- return;
-
- if (FBTrace.DBG_SPY)
- FBTrace.sysout("spy.detach; " + this.href);
-
- // Remove itself from the list of active spies.
- remove(this.context.spies, this);
-
- if (this.onreadystatechange)
- this.xhrRequest.onreadystatechange = this.onreadystatechange;
-
- try { this.xhrRequest.removeEventListener("load", this.onLoad, false); } catch (e) {}
- try { this.xhrRequest.removeEventListener("error", this.onError, false); } catch (e) {}
- try { this.xhrRequest.removeEventListener("abort", this.onAbort, false); } catch (e) {}
-
- this.onreadystatechange = null;
- this.onLoad = null;
- this.onError = null;
- this.onAbort = null;
-
- // xxxHonza: shouuld be removed from FB 1.6
- if (!SpyHttpActivityObserver.getActivityDistributor())
- this.context.sourceCache.removeListener(this);
- },
-
- getURL: function()
- {
- return this.xhrRequest.channel ? this.xhrRequest.channel.name : this.href;
- },
-
- // Cache listener
- onStopRequest: function(context, request, responseText)
- {
- if (!responseText)
- return;
-
- if (request == this.request)
- this.responseText = responseText;
- },
-};
-/**/
-// ************************************************************************************************
-/*
-function onHTTPSpyReadyStateChange(spy, event)
-{
- if (FBTrace.DBG_SPY)
- FBTrace.sysout("spy.onHTTPSpyReadyStateChange " + spy.xhrRequest.readyState +
- " (multipart: " + spy.xhrRequest.multipart + ")");
-
- // Remember just in case spy is detached (readyState == 4).
- var originalHandler = spy.onreadystatechange;
-
- // Force response text to be updated in the UI (in case the console entry
- // has been already expanded and the response tab selected).
- if (spy.logRow && spy.xhrRequest.readyState >= 3)
- {
- var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody");
- if (netInfoBox)
- {
- netInfoBox.htmlPresented = false;
- netInfoBox.responsePresented = false;
- }
- }
-
- // If the request is loading update the end time.
- if (spy.xhrRequest.readyState == 3)
- {
- spy.responseTime = spy.endTime - spy.sendTime;
- updateTime(spy);
- }
-
- // Request loaded. Get all the info from the request now, just in case the
- // XHR would be aborted in the original onReadyStateChange handler.
- if (spy.xhrRequest.readyState == 4)
- {
- // Cumulate response so, multipart response content is properly displayed.
- if (SpyHttpActivityObserver.getActivityDistributor())
- spy.responseText += spy.xhrRequest.responseText;
- else
- {
- // xxxHonza: remove from FB 1.6
- if (!spy.responseText)
- spy.responseText = spy.xhrRequest.responseText;
- }
-
- // The XHR is loaded now (used also by the activity observer).
- spy.loaded = true;
-
- // Update UI.
- updateHttpSpyInfo(spy);
-
- // Notify Net pane about a request beeing loaded.
- // xxxHonza: I don't think this is necessary.
- var netProgress = spy.context.netProgress;
- if (netProgress)
- netProgress.post(netProgress.stopFile, [spy.request, spy.endTime, spy.postText, spy.responseText]);
-
- // Notify registered listeners about finish of the XHR.
- dispatch(Firebug.Spy.fbListeners, "onLoad", [spy.context, spy]);
- }
-
- // Pass the event to the original page handler.
- callPageHandler(spy, event, originalHandler);
-}
-
-function onHTTPSpyLoad(spy)
-{
- if (FBTrace.DBG_SPY)
- FBTrace.sysout("spy.onHTTPSpyLoad: " + spy.href, spy);
-
- // Detach must be done in onLoad (not in onreadystatechange) otherwise
- // onAbort would not be handled.
- spy.detach();
-
- // xxxHonza: Still needed for Fx 3.5 (#502959)
- if (!SpyHttpActivityObserver.getActivityDistributor())
- onHTTPSpyReadyStateChange(spy, null);
-}
-
-function onHTTPSpyError(spy)
-{
- if (FBTrace.DBG_SPY)
- FBTrace.sysout("spy.onHTTPSpyError; " + spy.href, spy);
-
- spy.detach();
- spy.loaded = true;
-
- if (spy.logRow)
- {
- removeClass(spy.logRow, "loading");
- setClass(spy.logRow, "error");
- }
-}
-
-function onHTTPSpyAbort(spy)
-{
- if (FBTrace.DBG_SPY)
- FBTrace.sysout("spy.onHTTPSpyAbort: " + spy.href, spy);
-
- spy.detach();
- spy.loaded = true;
-
- if (spy.logRow)
- {
- removeClass(spy.logRow, "loading");
- setClass(spy.logRow, "error");
- }
-
- spy.statusText = "Aborted";
- updateLogRow(spy);
-
- // Notify Net pane about a request beeing aborted.
- // xxxHonza: the net panel shoud find out this itself.
- var netProgress = spy.context.netProgress;
- if (netProgress)
- netProgress.post(netProgress.abortFile, [spy.request, spy.endTime, spy.postText, spy.responseText]);
-}
-/**/
-
-// ************************************************************************************************
-
-/**
- * @domplate Represents a template for XHRs logged in the Console panel. The body of the
- * log (displayed when expanded) is rendered using {@link Firebug.NetMonitor.NetInfoBody}.
- */
-
-Firebug.Spy.XHR = domplate(Firebug.Rep,
-/** @lends Firebug.Spy.XHR */
-
-{
- tag:
- DIV({"class": "spyHead", _repObject: "$object"},
- TABLE({"class": "spyHeadTable focusRow outerFocusRow", cellpadding: 0, cellspacing: 0,
- "role": "listitem", "aria-expanded": "false"},
- TBODY({"role": "presentation"},
- TR({"class": "spyRow"},
- TD({"class": "spyTitleCol spyCol", onclick: "$onToggleBody"},
- DIV({"class": "spyTitle"},
- "$object|getCaption"
- ),
- DIV({"class": "spyFullTitle spyTitle"},
- "$object|getFullUri"
- )
- ),
- TD({"class": "spyCol"},
- DIV({"class": "spyStatus"}, "$object|getStatus")
- ),
- TD({"class": "spyCol"},
- SPAN({"class": "spyIcon"})
- ),
- TD({"class": "spyCol"},
- SPAN({"class": "spyTime"})
- ),
- TD({"class": "spyCol"},
- TAG(FirebugReps.SourceLink.tag, {object: "$object.sourceLink"})
- )
- )
- )
- )
- ),
-
- getCaption: function(spy)
- {
- return spy.method.toUpperCase() + " " + cropString(spy.getURL(), 100);
- },
-
- getFullUri: function(spy)
- {
- return spy.method.toUpperCase() + " " + spy.getURL();
- },
-
- getStatus: function(spy)
- {
- var text = "";
- if (spy.statusCode)
- text += spy.statusCode + " ";
-
- if (spy.statusText)
- return text += spy.statusText;
-
- return text;
- },
-
- onToggleBody: function(event)
- {
- var target = event.currentTarget || event.srcElement;
- var logRow = getAncestorByClass(target, "logRow-spy");
-
- if (isLeftClick(event))
- {
- toggleClass(logRow, "opened");
-
- var spy = getChildByClass(logRow, "spyHead").repObject;
- var spyHeadTable = getAncestorByClass(target, "spyHeadTable");
-
- if (hasClass(logRow, "opened"))
- {
- updateHttpSpyInfo(spy, logRow);
- if (spyHeadTable)
- spyHeadTable.setAttribute('aria-expanded', 'true');
- }
- else
- {
- //var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody");
- //dispatch(Firebug.NetMonitor.NetInfoBody.fbListeners, "destroyTabBody", [netInfoBox, spy]);
- //if (spyHeadTable)
- // spyHeadTable.setAttribute('aria-expanded', 'false');
- }
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- copyURL: function(spy)
- {
- copyToClipboard(spy.getURL());
- },
-
- copyParams: function(spy)
- {
- var text = spy.postText;
- if (!text)
- return;
-
- var url = reEncodeURL(spy, text, true);
- copyToClipboard(url);
- },
-
- copyResponse: function(spy)
- {
- copyToClipboard(spy.responseText);
- },
-
- openInTab: function(spy)
- {
- openNewTab(spy.getURL(), spy.postText);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- supportsObject: function(object)
- {
- // TODO: xxxpedro spy xhr
- return false;
-
- return object instanceof Firebug.Spy.XMLHttpRequestSpy;
- },
-
- browseObject: function(spy, context)
- {
- var url = spy.getURL();
- openNewTab(url);
- return true;
- },
-
- getRealObject: function(spy, context)
- {
- return spy.xhrRequest;
- },
-
- getContextMenuItems: function(spy)
- {
- var items = [
- {label: "CopyLocation", command: bindFixed(this.copyURL, this, spy) }
- ];
-
- if (spy.postText)
- {
- items.push(
- {label: "CopyLocationParameters", command: bindFixed(this.copyParams, this, spy) }
- );
- }
-
- items.push(
- {label: "CopyResponse", command: bindFixed(this.copyResponse, this, spy) },
- "-",
- {label: "OpenInTab", command: bindFixed(this.openInTab, this, spy) }
- );
-
- return items;
- }
-});
-
-// ************************************************************************************************
-
-function updateTime(spy)
-{
- var timeBox = spy.logRow.getElementsByClassName("spyTime").item(0);
- if (spy.responseTime)
- timeBox.textContent = " " + formatTime(spy.responseTime);
-}
-
-function updateLogRow(spy)
-{
- updateTime(spy);
-
- var statusBox = spy.logRow.getElementsByClassName("spyStatus").item(0);
- statusBox.textContent = Firebug.Spy.XHR.getStatus(spy);
-
- removeClass(spy.logRow, "loading");
- setClass(spy.logRow, "loaded");
-
- try
- {
- var errorRange = Math.floor(spy.xhrRequest.status/100);
- if (errorRange == 4 || errorRange == 5)
- setClass(spy.logRow, "error");
- }
- catch (exc)
- {
- }
-}
-
-var updateHttpSpyInfo = function updateHttpSpyInfo(spy, logRow)
-{
- if (!spy.logRow && logRow)
- spy.logRow = logRow;
-
- if (!spy.logRow || !hasClass(spy.logRow, "opened"))
- return;
-
- if (!spy.params)
- //spy.params = parseURLParams(spy.href+"");
- spy.params = parseURLParams(spy.href+"");
-
- if (!spy.requestHeaders)
- spy.requestHeaders = getRequestHeaders(spy);
-
- if (!spy.responseHeaders && spy.loaded)
- spy.responseHeaders = getResponseHeaders(spy);
-
- var template = Firebug.NetMonitor.NetInfoBody;
- var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody");
- if (!netInfoBox)
- {
- var head = getChildByClass(spy.logRow, "spyHead");
- netInfoBox = template.tag.append({"file": spy}, head);
- dispatch(template.fbListeners, "initTabBody", [netInfoBox, spy]);
- template.selectTabByName(netInfoBox, "Response");
- }
- else
- {
- template.updateInfo(netInfoBox, spy, spy.context);
- }
-};
-
-
-
-// ************************************************************************************************
-
-function getRequestHeaders(spy)
-{
- var headers = [];
-
- var channel = spy.xhrRequest.channel;
- if (channel instanceof Ci.nsIHttpChannel)
- {
- channel.visitRequestHeaders({
- visitHeader: function(name, value)
- {
- headers.push({name: name, value: value});
- }
- });
- }
-
- return headers;
-}
-
-function getResponseHeaders(spy)
-{
- var headers = [];
-
- try
- {
- var channel = spy.xhrRequest.channel;
- if (channel instanceof Ci.nsIHttpChannel)
- {
- channel.visitResponseHeaders({
- visitHeader: function(name, value)
- {
- headers.push({name: name, value: value});
- }
- });
- }
- }
- catch (exc)
- {
- if (FBTrace.DBG_SPY || FBTrace.DBG_ERRORS)
- FBTrace.sysout("spy.getResponseHeaders; EXCEPTION " +
- safeGetRequestName(spy.request), exc);
- }
-
- return headers;
-}
-
-// ************************************************************************************************
-// Registration
-
-Firebug.registerModule(Firebug.Spy);
-//Firebug.registerRep(Firebug.Spy.XHR);
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-
-// ************************************************************************************************
-
-// List of JSON content types.
-var contentTypes =
-{
- // TODO: create issue: jsonViewer will not try to evaluate the contents of the requested file
- // if the content-type is set to "text/plain"
- //"text/plain": 1,
- "text/javascript": 1,
- "text/x-javascript": 1,
- "text/json": 1,
- "text/x-json": 1,
- "application/json": 1,
- "application/x-json": 1,
- "application/javascript": 1,
- "application/x-javascript": 1,
- "application/json-rpc": 1
-};
-
-// ************************************************************************************************
-// Model implementation
-
-Firebug.JSONViewerModel = extend(Firebug.Module,
-{
- dispatchName: "jsonViewer",
- initialize: function()
- {
- Firebug.NetMonitor.NetInfoBody.addListener(this);
-
- // Used by Firebug.DOMPanel.DirTable domplate.
- this.toggles = {};
- },
-
- shutdown: function()
- {
- Firebug.NetMonitor.NetInfoBody.removeListener(this);
- },
-
- initTabBody: function(infoBox, file)
- {
- if (FBTrace.DBG_JSONVIEWER)
- FBTrace.sysout("jsonviewer.initTabBody", infoBox);
-
- // Let listeners to parse the JSON.
- dispatch(this.fbListeners, "onParseJSON", [file]);
-
- // The JSON is still no there, try to parse most common cases.
- if (!file.jsonObject)
- {
- ///if (this.isJSON(safeGetContentType(file.request), file.responseText))
- if (this.isJSON(file.mimeType, file.responseText))
- file.jsonObject = this.parseJSON(file);
- }
-
- // The jsonObject is created so, the JSON tab can be displayed.
- if (file.jsonObject && hasProperties(file.jsonObject))
- {
- Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "JSON",
- ///$STR("jsonviewer.tab.JSON"));
- $STR("JSON"));
-
- if (FBTrace.DBG_JSONVIEWER)
- FBTrace.sysout("jsonviewer.initTabBody; JSON object available " +
- (typeof(file.jsonObject) != "undefined"), file.jsonObject);
- }
- },
-
- isJSON: function(contentType, data)
- {
- // Workaround for JSON responses without proper content type
- // Let's consider all responses starting with "{" as JSON. In the worst
- // case there will be an exception when parsing. This means that no-JSON
- // responses (and post data) (with "{") can be parsed unnecessarily,
- // which represents a little overhead, but this happens only if the request
- // is actually expanded by the user in the UI (Net & Console panels).
-
- ///var responseText = data ? trimLeft(data) : null;
- ///if (responseText && responseText.indexOf("{") == 0)
- /// return true;
- var responseText = data ? trim(data) : null;
- if (responseText && responseText.indexOf("{") == 0)
- return true;
-
- if (!contentType)
- return false;
-
- contentType = contentType.split(";")[0];
- contentType = trim(contentType);
- return contentTypes[contentType];
- },
-
- // Update listener for TabView
- updateTabBody: function(infoBox, file, context)
- {
- var tab = infoBox.selectedTab;
- ///var tabBody = infoBox.getElementsByClassName("netInfoJSONText").item(0);
- var tabBody = $$(".netInfoJSONText", infoBox)[0];
- if (!hasClass(tab, "netInfoJSONTab") || tabBody.updated)
- return;
-
- tabBody.updated = true;
-
- if (file.jsonObject) {
- Firebug.DOMPanel.DirTable.tag.replace(
- {object: file.jsonObject, toggles: this.toggles}, tabBody);
- }
- },
-
- parseJSON: function(file)
- {
- var jsonString = new String(file.responseText);
- ///return parseJSONString(jsonString, "http://" + file.request.originalURI.host);
- return parseJSONString(jsonString);
- }
-});
-
-// ************************************************************************************************
-// Registration
-
-Firebug.registerModule(Firebug.JSONViewerModel);
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-
-// ************************************************************************************************
-// Constants
-
-// List of XML related content types.
-var xmlContentTypes =
-[
- "text/xml",
- "application/xml",
- "application/xhtml+xml",
- "application/rss+xml",
- "application/atom+xml",,
- "application/vnd.mozilla.maybe.feed",
- "application/rdf+xml",
- "application/vnd.mozilla.xul+xml"
-];
-
-// ************************************************************************************************
-// Model implementation
-
-/**
- * @module Implements viewer for XML based network responses. In order to create a new
- * tab wihin network request detail, a listener is registered into
- * <code>Firebug.NetMonitor.NetInfoBody</code> object.
- */
-Firebug.XMLViewerModel = extend(Firebug.Module,
-{
- dispatchName: "xmlViewer",
-
- initialize: function()
- {
- ///Firebug.ActivableModule.initialize.apply(this, arguments);
- Firebug.Module.initialize.apply(this, arguments);
- Firebug.NetMonitor.NetInfoBody.addListener(this);
- },
-
- shutdown: function()
- {
- ///Firebug.ActivableModule.shutdown.apply(this, arguments);
- Firebug.Module.shutdown.apply(this, arguments);
- Firebug.NetMonitor.NetInfoBody.removeListener(this);
- },
-
- /**
- * Check response's content-type and if it's a XML, create a new tab with XML preview.
- */
- initTabBody: function(infoBox, file)
- {
- if (FBTrace.DBG_XMLVIEWER)
- FBTrace.sysout("xmlviewer.initTabBody", infoBox);
-
- // If the response is XML let's display a pretty preview.
- ///if (this.isXML(safeGetContentType(file.request)))
- if (this.isXML(file.mimeType, file.responseText))
- {
- Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "XML",
- ///$STR("xmlviewer.tab.XML"));
- $STR("XML"));
-
- if (FBTrace.DBG_XMLVIEWER)
- FBTrace.sysout("xmlviewer.initTabBody; XML response available");
- }
- },
-
- isXML: function(contentType)
- {
- if (!contentType)
- return false;
-
- // Look if the response is XML based.
- for (var i=0; i<xmlContentTypes.length; i++)
- {
- if (contentType.indexOf(xmlContentTypes[i]) == 0)
- return true;
- }
-
- return false;
- },
-
- /**
- * Parse XML response and render pretty printed preview.
- */
- updateTabBody: function(infoBox, file, context)
- {
- var tab = infoBox.selectedTab;
- ///var tabBody = infoBox.getElementsByClassName("netInfoXMLText").item(0);
- var tabBody = $$(".netInfoXMLText", infoBox)[0];
- if (!hasClass(tab, "netInfoXMLTab") || tabBody.updated)
- return;
-
- tabBody.updated = true;
-
- this.insertXML(tabBody, Firebug.NetMonitor.Utils.getResponseText(file, context));
- },
-
- insertXML: function(parentNode, text)
- {
- var xmlText = text.replace(/^\s*<?.+?>\s*/, "");
-
- var div = parentNode.ownerDocument.createElement("div");
- div.innerHTML = xmlText;
-
- var root = div.getElementsByTagName("*")[0];
-
- /***
- var parser = CCIN("@mozilla.org/xmlextras/domparser;1", "nsIDOMParser");
- var doc = parser.parseFromString(text, "text/xml");
- var root = doc.documentElement;
-
- // Error handling
- var nsURI = "http://www.mozilla.org/newlayout/xml/parsererror.xml";
- if (root.namespaceURI == nsURI && root.nodeName == "parsererror")
- {
- this.ParseError.tag.replace({error: {
- message: root.firstChild.nodeValue,
- source: root.lastChild.textContent
- }}, parentNode);
- return;
- }
- /**/
-
- if (FBTrace.DBG_XMLVIEWER)
- FBTrace.sysout("xmlviewer.updateTabBody; XML response parsed", doc);
-
- // Override getHidden in these templates. The parsed XML documen is
- // hidden, but we want to display it using 'visible' styling.
- /*
- var templates = [
- Firebug.HTMLPanel.CompleteElement,
- Firebug.HTMLPanel.Element,
- Firebug.HTMLPanel.TextElement,
- Firebug.HTMLPanel.EmptyElement,
- Firebug.HTMLPanel.XEmptyElement,
- ];
-
- var originals = [];
- for (var i=0; i<templates.length; i++)
- {
- originals[i] = templates[i].getHidden;
- templates[i].getHidden = function() {
- return "";
- }
- }
- /**/
-
- // Generate XML preview.
- ///Firebug.HTMLPanel.CompleteElement.tag.replace({object: doc.documentElement}, parentNode);
-
- // TODO: xxxpedro html3
- ///Firebug.HTMLPanel.CompleteElement.tag.replace({object: root}, parentNode);
- var html = [];
- Firebug.Reps.appendNode(root, html);
- parentNode.innerHTML = html.join("");
-
-
- /*
- for (var i=0; i<originals.length; i++)
- templates[i].getHidden = originals[i];/**/
- }
-});
-
-// ************************************************************************************************
-// Domplate
-
-/**
- * @domplate Represents a template for displaying XML parser errors. Used by
- * <code>Firebug.XMLViewerModel</code>.
- */
-Firebug.XMLViewerModel.ParseError = domplate(Firebug.Rep,
-{
- tag:
- DIV({"class": "xmlInfoError"},
- DIV({"class": "xmlInfoErrorMsg"}, "$error.message"),
- PRE({"class": "xmlInfoErrorSource"}, "$error|getSource")
- ),
-
- getSource: function(error)
- {
- var parts = error.source.split("\n");
- if (parts.length != 2)
- return error.source;
-
- var limit = 50;
- var column = parts[1].length;
- if (column >= limit) {
- parts[0] = "..." + parts[0].substr(column - limit);
- parts[1] = "..." + parts[1].substr(column - limit);
- }
-
- if (parts[0].length > 80)
- parts[0] = parts[0].substr(0, 80) + "...";
-
- return parts.join("\n");
- }
-});
-
-// ************************************************************************************************
-// Registration
-
-Firebug.registerModule(Firebug.XMLViewerModel);
-
-}});
-
-
-/* See license.txt for terms of usage */
-
-// next-generation Console Panel (will override consoje.js)
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-// ************************************************************************************************
-// Constants
-
-/*
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const nsIPrefBranch2 = Ci.nsIPrefBranch2;
-const PrefService = Cc["@mozilla.org/preferences-service;1"];
-const prefs = PrefService.getService(nsIPrefBranch2);
-/**/
-/*
-
-// new offline message handler
-o = {x:1,y:2};
-
-r = Firebug.getRep(o);
-
-r.tag.tag.compile();
-
-outputs = [];
-html = r.tag.renderHTML({object:o}, outputs);
-
-
-// finish rendering the template (the DOM part)
-target = $("build");
-target.innerHTML = html;
-root = target.firstChild;
-
-domArgs = [root, r.tag.context, 0];
-domArgs.push.apply(domArgs, r.tag.domArgs);
-domArgs.push.apply(domArgs, outputs);
-r.tag.tag.renderDOM.apply(self ? self : r.tag.subject, domArgs);
-
-
- */
-var consoleQueue = [];
-var lastHighlightedObject;
-var FirebugContext = Env.browser;
-
-// ************************************************************************************************
-
-var maxQueueRequests = 500;
-
-// ************************************************************************************************
-
-Firebug.ConsoleBase =
-{
- log: function(object, context, className, rep, noThrottle, sourceLink)
- {
- //dispatch(this.fbListeners,"log",[context, object, className, sourceLink]);
- return this.logRow(appendObject, object, context, className, rep, sourceLink, noThrottle);
- },
-
- logFormatted: function(objects, context, className, noThrottle, sourceLink)
- {
- //dispatch(this.fbListeners,"logFormatted",[context, objects, className, sourceLink]);
- return this.logRow(appendFormatted, objects, context, className, null, sourceLink, noThrottle);
- },
-
- openGroup: function(objects, context, className, rep, noThrottle, sourceLink, noPush)
- {
- return this.logRow(appendOpenGroup, objects, context, className, rep, sourceLink, noThrottle);
- },
-
- closeGroup: function(context, noThrottle)
- {
- return this.logRow(appendCloseGroup, null, context, null, null, null, noThrottle, true);
- },
-
- logRow: function(appender, objects, context, className, rep, sourceLink, noThrottle, noRow)
- {
- // TODO: xxxpedro console console2
- noThrottle = true; // xxxpedro forced because there is no TabContext yet
-
- if (!context)
- context = FirebugContext;
-
- if (FBTrace.DBG_ERRORS && !context)
- FBTrace.sysout("Console.logRow has no context, skipping objects", objects);
-
- if (!context)
- return;
-
- if (noThrottle || !context)
- {
- var panel = this.getPanel(context);
- if (panel)
- {
- var row = panel.append(appender, objects, className, rep, sourceLink, noRow);
- var container = panel.panelNode;
-
- // TODO: xxxpedro what is this? console console2
- /*
- var template = Firebug.NetMonitor.NetLimit;
-
- while (container.childNodes.length > maxQueueRequests + 1)
- {
- clearDomplate(container.firstChild.nextSibling);
- container.removeChild(container.firstChild.nextSibling);
- panel.limit.limitInfo.totalCount++;
- template.updateCounter(panel.limit);
- }
- dispatch([Firebug.A11yModel], "onLogRowCreated", [panel , row]);
- /**/
- return row;
- }
- else
- {
- consoleQueue.push([appender, objects, context, className, rep, sourceLink, noThrottle, noRow]);
- }
- }
- else
- {
- if (!context.throttle)
- {
- //FBTrace.sysout("console.logRow has not context.throttle! ");
- return;
- }
- var args = [appender, objects, context, className, rep, sourceLink, true, noRow];
- context.throttle(this.logRow, this, args);
- }
- },
-
- appendFormatted: function(args, row, context)
- {
- if (!context)
- context = FirebugContext;
-
- var panel = this.getPanel(context);
- panel.appendFormatted(args, row);
- },
-
- clear: function(context)
- {
- if (!context)
- //context = FirebugContext;
- context = Firebug.context;
-
- /*
- if (context)
- Firebug.Errors.clear(context);
- /**/
-
- var panel = this.getPanel(context, true);
- if (panel)
- {
- panel.clear();
- }
- },
-
- // Override to direct output to your panel
- getPanel: function(context, noCreate)
- {
- //return context.getPanel("console", noCreate);
- // TODO: xxxpedro console console2
- return Firebug.chrome ? Firebug.chrome.getPanel("Console") : null;
- }
-
-};
-
-// ************************************************************************************************
-
-//TODO: xxxpedro
-//var ActivableConsole = extend(Firebug.ActivableModule, Firebug.ConsoleBase);
-var ActivableConsole = extend(Firebug.ConsoleBase,
-{
- isAlwaysEnabled: function()
- {
- return true;
- }
-});
-
-Firebug.Console = Firebug.Console = extend(ActivableConsole,
-//Firebug.Console = extend(ActivableConsole,
-{
- dispatchName: "console",
-
- error: function()
- {
- Firebug.Console.logFormatted(arguments, Firebug.browser, "error");
- },
-
- flush: function()
- {
- dispatch(this.fbListeners,"flush",[]);
-
- for (var i=0, length=consoleQueue.length; i<length; i++)
- {
- var args = consoleQueue[i];
- this.logRow.apply(this, args);
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // extends Module
-
- showPanel: function(browser, panel)
- {
- },
-
- getFirebugConsoleElement: function(context, win)
- {
- var element = win.document.getElementById("_firebugConsole");
- if (!element)
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("getFirebugConsoleElement forcing element");
- var elementForcer = "(function(){var r=null; try { r = window._getFirebugConsoleElement();}catch(exc){r=exc;} return r;})();"; // we could just add the elements here
-
- if (context.stopped)
- Firebug.Console.injector.evaluateConsoleScript(context); // todo evaluate consoleForcer on stack
- else
- var r = Firebug.CommandLine.evaluateInWebPage(elementForcer, context, win);
-
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("getFirebugConsoleElement forcing element result "+r, r);
-
- var element = win.document.getElementById("_firebugConsole");
- if (!element) // elementForce fails
- {
- if (FBTrace.DBG_ERRORS) FBTrace.sysout("console.getFirebugConsoleElement: no _firebugConsole in win:", win);
- Firebug.Console.logFormatted(["Firebug cannot find _firebugConsole element", r, win], context, "error", true);
- }
- }
-
- return element;
- },
-
- isReadyElsePreparing: function(context, win) // this is the only code that should call injector.attachIfNeeded
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("console.isReadyElsePreparing, win is " +
- (win?"an argument: ":"null, context.window: ") +
- (win?win.location:context.window.location), (win?win:context.window));
-
- if (win)
- return this.injector.attachIfNeeded(context, win);
- else
- {
- var attached = true;
- for (var i = 0; i < context.windows.length; i++)
- attached = attached && this.injector.attachIfNeeded(context, context.windows[i]);
- // already in the list above attached = attached && this.injector.attachIfNeeded(context, context.window);
- if (context.windows.indexOf(context.window) == -1)
- FBTrace.sysout("isReadyElsePreparing ***************** context.window not in context.windows");
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("console.isReadyElsePreparing attached to "+context.windows.length+" and returns "+attached);
- return attached;
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // extends ActivableModule
-
- initialize: function()
- {
- this.panelName = "console";
-
- //TODO: xxxpedro
- //Firebug.ActivableModule.initialize.apply(this, arguments);
- //Firebug.Debugger.addListener(this);
- },
-
- enable: function()
- {
- if (Firebug.Console.isAlwaysEnabled())
- this.watchForErrors();
- },
-
- disable: function()
- {
- if (Firebug.Console.isAlwaysEnabled())
- this.unwatchForErrors();
- },
-
- initContext: function(context, persistedState)
- {
- Firebug.ActivableModule.initContext.apply(this, arguments);
- context.consoleReloadWarning = true; // mark as need to warn.
- },
-
- loadedContext: function(context)
- {
- for (var url in context.sourceFileMap)
- return; // if there are any sourceFiles, then do nothing
-
- // else we saw no JS, so the reload warning it not needed.
- this.clearReloadWarning(context);
- },
-
- clearReloadWarning: function(context) // remove the warning about reloading.
- {
- if (context.consoleReloadWarning)
- {
- var panel = context.getPanel(this.panelName);
- panel.clearReloadWarning();
- delete context.consoleReloadWarning;
- }
- },
-
- togglePersist: function(context)
- {
- var panel = context.getPanel(this.panelName);
- panel.persistContent = panel.persistContent ? false : true;
- Firebug.chrome.setGlobalAttribute("cmd_togglePersistConsole", "checked", panel.persistContent);
- },
-
- showContext: function(browser, context)
- {
- Firebug.chrome.setGlobalAttribute("cmd_clearConsole", "disabled", !context);
-
- Firebug.ActivableModule.showContext.apply(this, arguments);
- },
-
- destroyContext: function(context, persistedState)
- {
- Firebug.Console.injector.detachConsole(context, context.window); // TODO iterate windows?
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- onPanelEnable: function(panelName)
- {
- if (panelName != this.panelName) // we don't care about other panels
- return;
-
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("console.onPanelEnable**************");
-
- this.watchForErrors();
- Firebug.Debugger.addDependentModule(this); // we inject the console during JS compiles so we need jsd
- },
-
- onPanelDisable: function(panelName)
- {
- if (panelName != this.panelName) // we don't care about other panels
- return;
-
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("console.onPanelDisable**************");
-
- Firebug.Debugger.removeDependentModule(this); // we inject the console during JS compiles so we need jsd
- this.unwatchForErrors();
-
- // Make sure possible errors coming from the page and displayed in the Firefox
- // status bar are removed.
- this.clear();
- },
-
- onSuspendFirebug: function()
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("console.onSuspendFirebug\n");
- if (Firebug.Console.isAlwaysEnabled())
- this.unwatchForErrors();
- },
-
- onResumeFirebug: function()
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("console.onResumeFirebug\n");
- if (Firebug.Console.isAlwaysEnabled())
- this.watchForErrors();
- },
-
- watchForErrors: function()
- {
- Firebug.Errors.checkEnabled();
- $('fbStatusIcon').setAttribute("console", "on");
- },
-
- unwatchForErrors: function()
- {
- Firebug.Errors.checkEnabled();
- $('fbStatusIcon').removeAttribute("console");
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Firebug.Debugger listener
-
- onMonitorScript: function(context, frame)
- {
- Firebug.Console.log(frame, context);
- },
-
- onFunctionCall: function(context, frame, depth, calling)
- {
- if (calling)
- Firebug.Console.openGroup([frame, "depth:"+depth], context);
- else
- Firebug.Console.closeGroup(context);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- logRow: function(appender, objects, context, className, rep, sourceLink, noThrottle, noRow)
- {
- if (!context)
- context = FirebugContext;
-
- if (FBTrace.DBG_WINDOWS && !context) FBTrace.sysout("Console.logRow: no context \n");
-
- if (this.isAlwaysEnabled())
- return Firebug.ConsoleBase.logRow.apply(this, arguments);
- }
-});
-
-Firebug.ConsoleListener =
-{
- log: function(context, object, className, sourceLink)
- {
- },
-
- logFormatted: function(context, objects, className, sourceLink)
- {
- }
-};
-
-// ************************************************************************************************
-
-Firebug.ConsolePanel = function () {} // XXjjb attach Firebug so this panel can be extended.
-
-//TODO: xxxpedro
-//Firebug.ConsolePanel.prototype = extend(Firebug.ActivablePanel,
-Firebug.ConsolePanel.prototype = extend(Firebug.Panel,
-{
- wasScrolledToBottom: false,
- messageCount: 0,
- lastLogTime: 0,
- groups: null,
- limit: null,
-
- append: function(appender, objects, className, rep, sourceLink, noRow)
- {
- var container = this.getTopContainer();
-
- if (noRow)
- {
- appender.apply(this, [objects]);
- }
- else
- {
- // xxxHonza: Don't update the this.wasScrolledToBottom flag now.
- // At the beginning (when the first log is created) the isScrolledToBottom
- // always returns true.
- //if (this.panelNode.offsetHeight)
- // this.wasScrolledToBottom = isScrolledToBottom(this.panelNode);
-
- var row = this.createRow("logRow", className);
- appender.apply(this, [objects, row, rep]);
-
- if (sourceLink)
- FirebugReps.SourceLink.tag.append({object: sourceLink}, row);
-
- container.appendChild(row);
-
- this.filterLogRow(row, this.wasScrolledToBottom);
-
- if (this.wasScrolledToBottom)
- scrollToBottom(this.panelNode);
-
- return row;
- }
- },
-
- clear: function()
- {
- if (this.panelNode)
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("ConsolePanel.clear");
- clearNode(this.panelNode);
- this.insertLogLimit(this.context);
- }
- },
-
- insertLogLimit: function()
- {
- // Create limit row. This row is the first in the list of entries
- // and initially hidden. It's displayed as soon as the number of
- // entries reaches the limit.
- var row = this.createRow("limitRow");
-
- var limitInfo = {
- totalCount: 0,
- limitPrefsTitle: $STRF("LimitPrefsTitle", [Firebug.prefDomain+".console.logLimit"])
- };
-
- //TODO: xxxpedro console net limit!?
- return;
- var netLimitRep = Firebug.NetMonitor.NetLimit;
- var nodes = netLimitRep.createTable(row, limitInfo);
-
- this.limit = nodes[1];
-
- var container = this.panelNode;
- container.insertBefore(nodes[0], container.firstChild);
- },
-
- insertReloadWarning: function()
- {
- // put the message in, we will clear if the window console is injected.
- this.warningRow = this.append(appendObject, $STR("message.Reload to activate window console"), "info");
- },
-
- clearReloadWarning: function()
- {
- if (this.warningRow)
- {
- this.warningRow.parentNode.removeChild(this.warningRow);
- delete this.warningRow;
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- appendObject: function(object, row, rep)
- {
- if (!rep)
- rep = Firebug.getRep(object);
- return rep.tag.append({object: object}, row);
- },
-
- appendFormatted: function(objects, row, rep)
- {
- if (!objects || !objects.length)
- return;
-
- function logText(text, row)
- {
- var node = row.ownerDocument.createTextNode(text);
- row.appendChild(node);
- }
-
- var format = objects[0];
- var objIndex = 0;
-
- if (typeof(format) != "string")
- {
- format = "";
- objIndex = -1;
- }
- else // a string
- {
- if (objects.length === 1) // then we have only a string...
- {
- if (format.length < 1) { // ...and it has no characters.
- logText("(an empty string)", row);
- return;
- }
- }
- }
-
- var parts = parseFormat(format);
- var trialIndex = objIndex;
- for (var i= 0; i < parts.length; i++)
- {
- var part = parts[i];
- if (part && typeof(part) == "object")
- {
- if (++trialIndex > objects.length) // then too few parameters for format, assume unformatted.
- {
- format = "";
- objIndex = -1;
- parts.length = 0;
- break;
- }
- }
-
- }
- for (var i = 0; i < parts.length; ++i)
- {
- var part = parts[i];
- if (part && typeof(part) == "object")
- {
- var object = objects[++objIndex];
- if (typeof(object) != "undefined")
- this.appendObject(object, row, part.rep);
- else
- this.appendObject(part.type, row, FirebugReps.Text);
- }
- else
- FirebugReps.Text.tag.append({object: part}, row);
- }
-
- for (var i = objIndex+1; i < objects.length; ++i)
- {
- logText(" ", row);
- var object = objects[i];
- if (typeof(object) == "string")
- FirebugReps.Text.tag.append({object: object}, row);
- else
- this.appendObject(object, row);
- }
- },
-
- appendOpenGroup: function(objects, row, rep)
- {
- if (!this.groups)
- this.groups = [];
-
- setClass(row, "logGroup");
- setClass(row, "opened");
-
- var innerRow = this.createRow("logRow");
- setClass(innerRow, "logGroupLabel");
- if (rep)
- rep.tag.replace({"objects": objects}, innerRow);
- else
- this.appendFormatted(objects, innerRow, rep);
- row.appendChild(innerRow);
- //dispatch([Firebug.A11yModel], 'onLogRowCreated', [this, innerRow]);
- var groupBody = this.createRow("logGroupBody");
- row.appendChild(groupBody);
- groupBody.setAttribute('role', 'group');
- this.groups.push(groupBody);
-
- addEvent(innerRow, "mousedown", function(event)
- {
- if (isLeftClick(event))
- {
- //console.log(event.currentTarget == event.target);
-
- var target = event.target || event.srcElement;
-
- target = getAncestorByClass(target, "logGroupLabel");
-
- var groupRow = target.parentNode;
-
- if (hasClass(groupRow, "opened"))
- {
- removeClass(groupRow, "opened");
- target.setAttribute('aria-expanded', 'false');
- }
- else
- {
- setClass(groupRow, "opened");
- target.setAttribute('aria-expanded', 'true');
- }
- }
- });
- },
-
- appendCloseGroup: function(object, row, rep)
- {
- if (this.groups)
- this.groups.pop();
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // TODO: xxxpedro console2
- onMouseMove: function(event)
- {
- if (!Firebug.Inspector) return;
-
- var target = event.srcElement || event.target;
-
- var object = getAncestorByClass(target, "objectLink-element");
- object = object ? object.repObject : null;
-
- if(object && instanceOf(object, "Element") && object.nodeType == 1)
- {
- if(object != lastHighlightedObject)
- {
- Firebug.Inspector.drawBoxModel(object);
- object = lastHighlightedObject;
- }
- }
- else
- Firebug.Inspector.hideBoxModel();
-
- },
-
- onMouseDown: function(event)
- {
- var target = event.srcElement || event.target;
-
- var object = getAncestorByClass(target, "objectLink");
- var repObject = object ? object.repObject : null;
-
- if (!repObject)
- {
- return;
- }
-
- if (hasClass(object, "objectLink-object"))
- {
- Firebug.chrome.selectPanel("DOM");
- Firebug.chrome.getPanel("DOM").select(repObject, true);
- }
- else if (hasClass(object, "objectLink-element"))
- {
- Firebug.chrome.selectPanel("HTML");
- Firebug.chrome.getPanel("HTML").select(repObject, true);
- }
-
- /*
- if(object && instanceOf(object, "Element") && object.nodeType == 1)
- {
- if(object != lastHighlightedObject)
- {
- Firebug.Inspector.drawBoxModel(object);
- object = lastHighlightedObject;
- }
- }
- else
- Firebug.Inspector.hideBoxModel();
- /**/
-
- },
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // extends Panel
-
- name: "Console",
- title: "Console",
- //searchable: true,
- //breakable: true,
- //editable: false,
-
- options:
- {
- hasCommandLine: true,
- hasToolButtons: true,
- isPreRendered: true
- },
-
- create: function()
- {
- Firebug.Panel.create.apply(this, arguments);
-
- this.context = Firebug.browser.window;
- this.document = Firebug.chrome.document;
- this.onMouseMove = bind(this.onMouseMove, this);
- this.onMouseDown = bind(this.onMouseDown, this);
-
- this.clearButton = new Button({
- element: $("fbConsole_btClear"),
- owner: Firebug.Console,
- onClick: Firebug.Console.clear
- });
- },
-
- initialize: function()
- {
- Firebug.Panel.initialize.apply(this, arguments); // loads persisted content
- //Firebug.ActivablePanel.initialize.apply(this, arguments); // loads persisted content
-
- if (!this.persistedContent && Firebug.Console.isAlwaysEnabled())
- {
- this.insertLogLimit(this.context);
-
- // Initialize log limit and listen for changes.
- this.updateMaxLimit();
-
- if (this.context.consoleReloadWarning) // we have not yet injected the console
- this.insertReloadWarning();
- }
-
- //Firebug.Console.injector.install(Firebug.browser.window);
-
- addEvent(this.panelNode, "mouseover", this.onMouseMove);
- addEvent(this.panelNode, "mousedown", this.onMouseDown);
-
- this.clearButton.initialize();
-
- //consolex.trace();
- //TODO: xxxpedro remove this
- /*
- Firebug.Console.openGroup(["asd"], null, "group", null, false);
- Firebug.Console.log("asd");
- Firebug.Console.log("asd");
- Firebug.Console.log("asd");
- /**/
-
- //TODO: xxxpedro preferences prefs
- //prefs.addObserver(Firebug.prefDomain, this, false);
- },
-
- initializeNode : function()
- {
- //dispatch([Firebug.A11yModel], 'onInitializeNode', [this]);
- if (FBTrace.DBG_CONSOLE)
- {
- this.onScroller = bind(this.onScroll, this);
- addEvent(this.panelNode, "scroll", this.onScroller);
- }
-
- this.onResizer = bind(this.onResize, this);
- this.resizeEventTarget = Firebug.chrome.$('fbContentBox');
- addEvent(this.resizeEventTarget, "resize", this.onResizer);
- },
-
- destroyNode : function()
- {
- //dispatch([Firebug.A11yModel], 'onDestroyNode', [this]);
- if (this.onScroller)
- removeEvent(this.panelNode, "scroll", this.onScroller);
-
- //removeEvent(this.resizeEventTarget, "resize", this.onResizer);
- },
-
- shutdown: function()
- {
- //TODO: xxxpedro console console2
- this.clearButton.shutdown();
-
- removeEvent(this.panelNode, "mousemove", this.onMouseMove);
- removeEvent(this.panelNode, "mousedown", this.onMouseDown);
-
- this.destroyNode();
-
- Firebug.Panel.shutdown.apply(this, arguments);
-
- //TODO: xxxpedro preferences prefs
- //prefs.removeObserver(Firebug.prefDomain, this, false);
- },
-
- ishow: function(state)
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("Console.panel show; " + this.context.getName(), state);
-
- var enabled = Firebug.Console.isAlwaysEnabled();
- if (enabled)
- {
- Firebug.Console.disabledPanelPage.hide(this);
- this.showCommandLine(true);
- this.showToolbarButtons("fbConsoleButtons", true);
- Firebug.chrome.setGlobalAttribute("cmd_togglePersistConsole", "checked", this.persistContent);
-
- if (state && state.wasScrolledToBottom)
- {
- this.wasScrolledToBottom = state.wasScrolledToBottom;
- delete state.wasScrolledToBottom;
- }
-
- if (this.wasScrolledToBottom)
- scrollToBottom(this.panelNode);
-
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("console.show ------------------ wasScrolledToBottom: " +
- this.wasScrolledToBottom + ", " + this.context.getName());
- }
- else
- {
- this.hide(state);
- Firebug.Console.disabledPanelPage.show(this);
- }
- },
-
- ihide: function(state)
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("Console.panel hide; " + this.context.getName(), state);
-
- this.showToolbarButtons("fbConsoleButtons", false);
- this.showCommandLine(false);
-
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("console.hide ------------------ wasScrolledToBottom: " +
- this.wasScrolledToBottom + ", " + this.context.getName());
- },
-
- destroy: function(state)
- {
- if (this.panelNode.offsetHeight)
- this.wasScrolledToBottom = isScrolledToBottom(this.panelNode);
-
- if (state)
- state.wasScrolledToBottom = this.wasScrolledToBottom;
-
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("console.destroy ------------------ wasScrolledToBottom: " +
- this.wasScrolledToBottom + ", " + this.context.getName());
- },
-
- shouldBreakOnNext: function()
- {
- // xxxHonza: shouldn't the breakOnErrors be context related?
- // xxxJJB, yes, but we can't support it because we can't yet tell
- // which window the error is on.
- return Firebug.getPref(Firebug.servicePrefDomain, "breakOnErrors");
- },
-
- getBreakOnNextTooltip: function(enabled)
- {
- return (enabled ? $STR("console.Disable Break On All Errors") :
- $STR("console.Break On All Errors"));
- },
-
- enablePanel: function(module)
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("console.ConsolePanel.enablePanel; " + this.context.getName());
-
- Firebug.ActivablePanel.enablePanel.apply(this, arguments);
-
- this.showCommandLine(true);
-
- if (this.wasScrolledToBottom)
- scrollToBottom(this.panelNode);
- },
-
- disablePanel: function(module)
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("console.ConsolePanel.disablePanel; " + this.context.getName());
-
- Firebug.ActivablePanel.disablePanel.apply(this, arguments);
-
- this.showCommandLine(false);
- },
-
- getOptionsMenuItems: function()
- {
- return [
- optionMenu("ShowJavaScriptErrors", "showJSErrors"),
- optionMenu("ShowJavaScriptWarnings", "showJSWarnings"),
- optionMenu("ShowCSSErrors", "showCSSErrors"),
- optionMenu("ShowXMLErrors", "showXMLErrors"),
- optionMenu("ShowXMLHttpRequests", "showXMLHttpRequests"),
- optionMenu("ShowChromeErrors", "showChromeErrors"),
- optionMenu("ShowChromeMessages", "showChromeMessages"),
- optionMenu("ShowExternalErrors", "showExternalErrors"),
- optionMenu("ShowNetworkErrors", "showNetworkErrors"),
- this.getShowStackTraceMenuItem(),
- this.getStrictOptionMenuItem(),
- "-",
- optionMenu("LargeCommandLine", "largeCommandLine")
- ];
- },
-
- getShowStackTraceMenuItem: function()
- {
- var menuItem = serviceOptionMenu("ShowStackTrace", "showStackTrace");
- if (FirebugContext && !Firebug.Debugger.isAlwaysEnabled())
- menuItem.disabled = true;
- return menuItem;
- },
-
- getStrictOptionMenuItem: function()
- {
- var strictDomain = "javascript.options";
- var strictName = "strict";
- var strictValue = prefs.getBoolPref(strictDomain+"."+strictName);
- return {label: "JavascriptOptionsStrict", type: "checkbox", checked: strictValue,
- command: bindFixed(Firebug.setPref, Firebug, strictDomain, strictName, !strictValue) };
- },
-
- getBreakOnMenuItems: function()
- {
- //xxxHonza: no BON options for now.
- /*return [
- optionMenu("console.option.Persist Break On Error", "persistBreakOnError")
- ];*/
- return [];
- },
-
- search: function(text)
- {
- if (!text)
- return;
-
- // Make previously visible nodes invisible again
- if (this.matchSet)
- {
- for (var i in this.matchSet)
- removeClass(this.matchSet[i], "matched");
- }
-
- this.matchSet = [];
-
- function findRow(node) { return getAncestorByClass(node, "logRow"); }
- var search = new TextSearch(this.panelNode, findRow);
-
- var logRow = search.find(text);
- if (!logRow)
- {
- dispatch([Firebug.A11yModel], 'onConsoleSearchMatchFound', [this, text, []]);
- return false;
- }
- for (; logRow; logRow = search.findNext())
- {
- setClass(logRow, "matched");
- this.matchSet.push(logRow);
- }
- dispatch([Firebug.A11yModel], 'onConsoleSearchMatchFound', [this, text, this.matchSet]);
- return true;
- },
-
- breakOnNext: function(breaking)
- {
- Firebug.setPref(Firebug.servicePrefDomain, "breakOnErrors", breaking);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // private
-
- createRow: function(rowName, className)
- {
- var elt = this.document.createElement("div");
- elt.className = rowName + (className ? " " + rowName + "-" + className : "");
- return elt;
- },
-
- getTopContainer: function()
- {
- if (this.groups && this.groups.length)
- return this.groups[this.groups.length-1];
- else
- return this.panelNode;
- },
-
- filterLogRow: function(logRow, scrolledToBottom)
- {
- if (this.searchText)
- {
- setClass(logRow, "matching");
- setClass(logRow, "matched");
-
- // Search after a delay because we must wait for a frame to be created for
- // the new logRow so that the finder will be able to locate it
- setTimeout(bindFixed(function()
- {
- if (this.searchFilter(this.searchText, logRow))
- this.matchSet.push(logRow);
- else
- removeClass(logRow, "matched");
-
- removeClass(logRow, "matching");
-
- if (scrolledToBottom)
- scrollToBottom(this.panelNode);
- }, this), 100);
- }
- },
-
- searchFilter: function(text, logRow)
- {
- var count = this.panelNode.childNodes.length;
- var searchRange = this.document.createRange();
- searchRange.setStart(this.panelNode, 0);
- searchRange.setEnd(this.panelNode, count);
-
- var startPt = this.document.createRange();
- startPt.setStartBefore(logRow);
-
- var endPt = this.document.createRange();
- endPt.setStartAfter(logRow);
-
- return finder.Find(text, searchRange, startPt, endPt) != null;
- },
-
- // nsIPrefObserver
- observe: function(subject, topic, data)
- {
- // We're observing preferences only.
- if (topic != "nsPref:changed")
- return;
-
- // xxxHonza check this out.
- var prefDomain = "Firebug.extension.";
- var prefName = data.substr(prefDomain.length);
- if (prefName == "console.logLimit")
- this.updateMaxLimit();
- },
-
- updateMaxLimit: function()
- {
- var value = 1000;
- //TODO: xxxpedro preferences log limit?
- //var value = Firebug.getPref(Firebug.prefDomain, "console.logLimit");
- maxQueueRequests = value ? value : maxQueueRequests;
- },
-
- showCommandLine: function(shouldShow)
- {
- //TODO: xxxpedro show command line important
- return;
-
- if (shouldShow)
- {
- collapse(Firebug.chrome.$("fbCommandBox"), false);
- Firebug.CommandLine.setMultiLine(Firebug.largeCommandLine, Firebug.chrome);
- }
- else
- {
- // Make sure that entire content of the Console panel is hidden when
- // the panel is disabled.
- Firebug.CommandLine.setMultiLine(false, Firebug.chrome, Firebug.largeCommandLine);
- collapse(Firebug.chrome.$("fbCommandBox"), true);
- }
- },
-
- onScroll: function(event)
- {
- // Update the scroll position flag if the position changes.
- this.wasScrolledToBottom = FBL.isScrolledToBottom(this.panelNode);
-
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("console.onScroll ------------------ wasScrolledToBottom: " +
- this.wasScrolledToBottom + ", wasScrolledToBottom: " +
- this.context.getName(), event);
- },
-
- onResize: function(event)
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("console.onResize ------------------ wasScrolledToBottom: " +
- this.wasScrolledToBottom + ", offsetHeight: " + this.panelNode.offsetHeight +
- ", scrollTop: " + this.panelNode.scrollTop + ", scrollHeight: " +
- this.panelNode.scrollHeight + ", " + this.context.getName(), event);
-
- if (this.wasScrolledToBottom)
- scrollToBottom(this.panelNode);
- }
-});
-
-// ************************************************************************************************
-
-function parseFormat(format)
-{
- var parts = [];
- if (format.length <= 0)
- return parts;
-
- var reg = /((^%|.%)(\d+)?(\.)([a-zA-Z]))|((^%|.%)([a-zA-Z]))/;
- for (var m = reg.exec(format); m; m = reg.exec(format))
- {
- if (m[0].substr(0, 2) == "%%")
- {
- parts.push(format.substr(0, m.index));
- parts.push(m[0].substr(1));
- }
- else
- {
- var type = m[8] ? m[8] : m[5];
- var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
-
- var rep = null;
- switch (type)
- {
- case "s":
- rep = FirebugReps.Text;
- break;
- case "f":
- case "i":
- case "d":
- rep = FirebugReps.Number;
- break;
- case "o":
- rep = null;
- break;
- }
-
- parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
- parts.push({rep: rep, precision: precision, type: ("%" + type)});
- }
-
- format = format.substr(m.index+m[0].length);
- }
-
- parts.push(format);
- return parts;
-}
-
-// ************************************************************************************************
-
-var appendObject = Firebug.ConsolePanel.prototype.appendObject;
-var appendFormatted = Firebug.ConsolePanel.prototype.appendFormatted;
-var appendOpenGroup = Firebug.ConsolePanel.prototype.appendOpenGroup;
-var appendCloseGroup = Firebug.ConsolePanel.prototype.appendCloseGroup;
-
-// ************************************************************************************************
-
-//Firebug.registerActivableModule(Firebug.Console);
-Firebug.registerModule(Firebug.Console);
-Firebug.registerPanel(Firebug.ConsolePanel);
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-
-// ************************************************************************************************
-// Constants
-
-//const Cc = Components.classes;
-//const Ci = Components.interfaces;
-
-var frameCounters = {};
-var traceRecursion = 0;
-
-Firebug.Console.injector =
-{
- install: function(context)
- {
- var win = context.window;
-
- var consoleHandler = new FirebugConsoleHandler(context, win);
-
- var properties =
- [
- "log",
- "debug",
- "info",
- "warn",
- "error",
- "assert",
- "dir",
- "dirxml",
- "group",
- "groupCollapsed",
- "groupEnd",
- "time",
- "timeEnd",
- "count",
- "trace",
- "profile",
- "profileEnd",
- "clear",
- "open",
- "close"
- ];
-
- var Handler = function(name)
- {
- var c = consoleHandler;
- var f = consoleHandler[name];
- return function(){return f.apply(c,arguments);};
- };
-
- var installer = function(c)
- {
- for (var i=0, l=properties.length; i<l; i++)
- {
- var name = properties[i];
- c[name] = new Handler(name);
- c.firebuglite = Firebug.version;
- }
- };
-
- var sandbox;
-
- if (win.console)
- {
- if (Env.Options.overrideConsole)
- sandbox = new win.Function("arguments.callee.install(window.console={})");
- else
- // if there's a console object and overrideConsole is false we should just quit
- return;
- }
- else
- {
- try
- {
- // try overriding the console object
- sandbox = new win.Function("arguments.callee.install(window.console={})");
- }
- catch(E)
- {
- // if something goes wrong create the firebug object instead
- sandbox = new win.Function("arguments.callee.install(window.firebug={})");
- }
- }
-
- sandbox.install = installer;
- sandbox();
- },
-
- isAttached: function(context, win)
- {
- if (win.wrappedJSObject)
- {
- var attached = (win.wrappedJSObject._getFirebugConsoleElement ? true : false);
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("Console.isAttached:"+attached+" to win.wrappedJSObject "+safeGetWindowLocation(win.wrappedJSObject));
-
- return attached;
- }
- else
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("Console.isAttached? to win "+win.location+" fnc:"+win._getFirebugConsoleElement);
- return (win._getFirebugConsoleElement ? true : false);
- }
- },
-
- attachIfNeeded: function(context, win)
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("Console.attachIfNeeded has win "+(win? ((win.wrappedJSObject?"YES":"NO")+" wrappedJSObject"):"null") );
-
- if (this.isAttached(context, win))
- return true;
-
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("Console.attachIfNeeded found isAttached false ");
-
- this.attachConsoleInjector(context, win);
- this.addConsoleListener(context, win);
-
- Firebug.Console.clearReloadWarning(context);
-
- var attached = this.isAttached(context, win);
- if (attached)
- dispatch(Firebug.Console.fbListeners, "onConsoleInjected", [context, win]);
-
- return attached;
- },
-
- attachConsoleInjector: function(context, win)
- {
- var consoleInjection = this.getConsoleInjectionScript(); // Do it all here.
-
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("attachConsoleInjector evaluating in "+win.location, consoleInjection);
-
- Firebug.CommandLine.evaluateInWebPage(consoleInjection, context, win);
-
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("attachConsoleInjector evaluation completed for "+win.location);
- },
-
- getConsoleInjectionScript: function() {
- if (!this.consoleInjectionScript)
- {
- var script = "";
- script += "window.__defineGetter__('console', function() {\n";
- script += " return (window._firebug ? window._firebug : window.loadFirebugConsole()); })\n\n";
-
- script += "window.loadFirebugConsole = function() {\n";
- script += "window._firebug = new _FirebugConsole();";
-
- if (FBTrace.DBG_CONSOLE)
- script += " window.dump('loadFirebugConsole '+window.location+'\\n');\n";
-
- script += " return window._firebug };\n";
-
- var theFirebugConsoleScript = getResource("chrome://firebug/content/consoleInjected.js");
- script += theFirebugConsoleScript;
-
-
- this.consoleInjectionScript = script;
- }
- return this.consoleInjectionScript;
- },
-
- forceConsoleCompilationInPage: function(context, win)
- {
- if (!win)
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("no win in forceConsoleCompilationInPage!");
- return;
- }
-
- var consoleForcer = "window.loadFirebugConsole();";
-
- if (context.stopped)
- Firebug.Console.injector.evaluateConsoleScript(context); // todo evaluate consoleForcer on stack
- else
- Firebug.CommandLine.evaluateInWebPage(consoleForcer, context, win);
-
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("forceConsoleCompilationInPage "+win.location, consoleForcer);
- },
-
- evaluateConsoleScript: function(context)
- {
- var scriptSource = this.getConsoleInjectionScript(); // TODO XXXjjb this should be getConsoleInjectionScript
- Firebug.Debugger.evaluate(scriptSource, context);
- },
-
- addConsoleListener: function(context, win)
- {
- if (!context.activeConsoleHandlers) // then we have not been this way before
- context.activeConsoleHandlers = [];
- else
- { // we've been this way before...
- for (var i=0; i<context.activeConsoleHandlers.length; i++)
- {
- if (context.activeConsoleHandlers[i].window == win)
- {
- context.activeConsoleHandlers[i].detach();
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("consoleInjector addConsoleListener removed handler("+context.activeConsoleHandlers[i].handler_name+") from _firebugConsole in : "+win.location+"\n");
- context.activeConsoleHandlers.splice(i,1);
- }
- }
- }
-
- // We need the element to attach our event listener.
- var element = Firebug.Console.getFirebugConsoleElement(context, win);
- if (element)
- element.setAttribute("FirebugVersion", Firebug.version); // Initialize Firebug version.
- else
- return false;
-
- var handler = new FirebugConsoleHandler(context, win);
- handler.attachTo(element);
-
- context.activeConsoleHandlers.push(handler);
-
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("consoleInjector addConsoleListener attached handler("+handler.handler_name+") to _firebugConsole in : "+win.location+"\n");
- return true;
- },
-
- detachConsole: function(context, win)
- {
- if (win && win.document)
- {
- var element = win.document.getElementById("_firebugConsole");
- if (element)
- element.parentNode.removeChild(element);
- }
- }
-};
-
-var total_handlers = 0;
-var FirebugConsoleHandler = function FirebugConsoleHandler(context, win)
-{
- this.window = win;
-
- this.attachTo = function(element)
- {
- this.element = element;
- // When raised on our injected element, callback to Firebug and append to console
- this.boundHandler = bind(this.handleEvent, this);
- this.element.addEventListener('firebugAppendConsole', this.boundHandler, true); // capturing
- };
-
- this.detach = function()
- {
- this.element.removeEventListener('firebugAppendConsole', this.boundHandler, true);
- };
-
- this.handler_name = ++total_handlers;
- this.handleEvent = function(event)
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("FirebugConsoleHandler("+this.handler_name+") "+event.target.getAttribute("methodName")+", event", event);
- if (!Firebug.CommandLine.CommandHandler.handle(event, this, win))
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("FirebugConsoleHandler", this);
-
- var methodName = event.target.getAttribute("methodName");
- Firebug.Console.log($STRF("console.MethodNotSupported", [methodName]));
- }
- };
-
- this.firebuglite = Firebug.version;
-
- this.init = function()
- {
- var consoleElement = win.document.getElementById('_firebugConsole');
- consoleElement.setAttribute("FirebugVersion", Firebug.version);
- };
-
- this.log = function()
- {
- logFormatted(arguments, "log");
- };
-
- this.debug = function()
- {
- logFormatted(arguments, "debug", true);
- };
-
- this.info = function()
- {
- logFormatted(arguments, "info", true);
- };
-
- this.warn = function()
- {
- logFormatted(arguments, "warn", true);
- };
-
- this.error = function()
- {
- //TODO: xxxpedro console error
- //if (arguments.length == 1)
- //{
- // logAssert("error", arguments); // add more info based on stack trace
- //}
- //else
- //{
- //Firebug.Errors.increaseCount(context);
- logFormatted(arguments, "error", true); // user already added info
- //}
- };
-
- this.exception = function()
- {
- logAssert("error", arguments);
- };
-
- this.assert = function(x)
- {
- if (!x)
- {
- var rest = [];
- for (var i = 1; i < arguments.length; i++)
- rest.push(arguments[i]);
- logAssert("assert", rest);
- }
- };
-
- this.dir = function(o)
- {
- Firebug.Console.log(o, context, "dir", Firebug.DOMPanel.DirTable);
- };
-
- this.dirxml = function(o)
- {
- ///if (o instanceof Window)
- if (instanceOf(o, "Window"))
- o = o.document.documentElement;
- ///else if (o instanceof Document)
- else if (instanceOf(o, "Document"))
- o = o.documentElement;
-
- Firebug.Console.log(o, context, "dirxml", Firebug.HTMLPanel.SoloElement);
- };
-
- this.group = function()
- {
- //TODO: xxxpedro;
- //var sourceLink = getStackLink();
- var sourceLink = null;
- Firebug.Console.openGroup(arguments, null, "group", null, false, sourceLink);
- };
-
- this.groupEnd = function()
- {
- Firebug.Console.closeGroup(context);
- };
-
- this.groupCollapsed = function()
- {
- var sourceLink = getStackLink();
- // noThrottle true is probably ok, openGroups will likely be short strings.
- var row = Firebug.Console.openGroup(arguments, null, "group", null, true, sourceLink);
- removeClass(row, "opened");
- };
-
- this.profile = function(title)
- {
- logFormatted(["console.profile() not supported."], "warn", true);
-
- //Firebug.Profiler.startProfiling(context, title);
- };
-
- this.profileEnd = function()
- {
- logFormatted(["console.profile() not supported."], "warn", true);
-
- //Firebug.Profiler.stopProfiling(context);
- };
-
- this.count = function(key)
- {
- // TODO: xxxpedro console2: is there a better way to find a unique ID for the coun() call?
- var frameId = "0";
- //var frameId = FBL.getStackFrameId();
- if (frameId)
- {
- if (!frameCounters)
- frameCounters = {};
-
- if (key != undefined)
- frameId += key;
-
- var frameCounter = frameCounters[frameId];
- if (!frameCounter)
- {
- var logRow = logFormatted(["0"], null, true, true);
-
- frameCounter = {logRow: logRow, count: 1};
- frameCounters[frameId] = frameCounter;
- }
- else
- ++frameCounter.count;
-
- var label = key == undefined
- ? frameCounter.count
- : key + " " + frameCounter.count;
-
- frameCounter.logRow.firstChild.firstChild.nodeValue = label;
- }
- };
-
- this.trace = function()
- {
- var getFuncName = function getFuncName (f)
- {
- if (f.getName instanceof Function)
- {
- return f.getName();
- }
- if (f.name) // in FireFox, Function objects have a name property...
- {
- return f.name;
- }
-
- var name = f.toString().match(/function\s*([_$\w\d]*)/)[1];
- return name || "anonymous";
- };
-
- var wasVisited = function(fn)
- {
- for (var i=0, l=frames.length; i<l; i++)
- {
- if (frames[i].fn == fn)
- {
- return true;
- }
- }
-
- return false;
- };
-
- traceRecursion++;
-
- if (traceRecursion > 1)
- {
- traceRecursion--;
- return;
- }
-
- var frames = [];
-
- for (var fn = arguments.callee.caller.caller; fn; fn = fn.caller)
- {
- if (wasVisited(fn)) break;
-
- var args = [];
-
- for (var i = 0, l = fn.arguments.length; i < l; ++i)
- {
- args.push({value: fn.arguments[i]});
- }
-
- frames.push({fn: fn, name: getFuncName(fn), args: args});
- }
-
-
- // ****************************************************************************************
-
- try
- {
- (0)();
- }
- catch(e)
- {
- var result = e;
-
- var stack =
- result.stack || // Firefox / Google Chrome
- result.stacktrace || // Opera
- "";
-
- stack = stack.replace(/\n\r|\r\n/g, "\n"); // normalize line breaks
- var items = stack.split(/[\n\r]/);
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Google Chrome
- if (FBL.isSafari)
- {
- //var reChromeStackItem = /^\s+at\s+([^\(]+)\s\((.*)\)$/;
- //var reChromeStackItem = /^\s+at\s+(.*)((?:http|https|ftp|file):\/\/.*)$/;
- var reChromeStackItem = /^\s+at\s+(.*)((?:http|https|ftp|file):\/\/.*)$/;
-
- var reChromeStackItemName = /\s*\($/;
- var reChromeStackItemValue = /^(.+)\:(\d+\:\d+)\)?$/;
-
- var framePos = 0;
- for (var i=4, length=items.length; i<length; i++, framePos++)
- {
- var frame = frames[framePos];
- var item = items[i];
- var match = item.match(reChromeStackItem);
-
- //Firebug.Console.log("["+ framePos +"]--------------------------");
- //Firebug.Console.log(item);
- //Firebug.Console.log("................");
-
- if (match)
- {
- var name = match[1];
- if (name)
- {
- name = name.replace(reChromeStackItemName, "");
- frame.name = name;
- }
-
- //Firebug.Console.log("name: "+name);
-
- var value = match[2].match(reChromeStackItemValue);
- if (value)
- {
- frame.href = value[1];
- frame.lineNo = value[2];
-
- //Firebug.Console.log("url: "+value[1]);
- //Firebug.Console.log("line: "+value[2]);
- }
- //else
- // Firebug.Console.log(match[2]);
-
- }
- }
- }
- /**/
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- else if (FBL.isFirefox)
- {
- // Firefox
- var reFirefoxStackItem = /^(.*)@(.*)$/;
- var reFirefoxStackItemValue = /^(.+)\:(\d+)$/;
-
- var framePos = 0;
- for (var i=2, length=items.length; i<length; i++, framePos++)
- {
- var frame = frames[framePos] || {};
- var item = items[i];
- var match = item.match(reFirefoxStackItem);
-
- if (match)
- {
- var name = match[1];
-
- //Firebug.Console.logFormatted("name: "+name);
-
- var value = match[2].match(reFirefoxStackItemValue);
- if (value)
- {
- frame.href = value[1];
- frame.lineNo = value[2];
-
- //Firebug.Console.log("href: "+ value[1]);
- //Firebug.Console.log("line: " + value[2]);
- }
- //else
- // Firebug.Console.logFormatted([match[2]]);
- }
- }
- }
- /**/
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- /*
- else if (FBL.isOpera)
- {
- // Opera
- var reOperaStackItem = /^\s\s(?:\.\.\.\s\s)?Line\s(\d+)\sof\s(.+)$/;
- var reOperaStackItemValue = /^linked\sscript\s(.+)$/;
-
- for (var i=0, length=items.length; i<length; i+=2)
- {
- var item = items[i];
-
- var match = item.match(reOperaStackItem);
-
- if (match)
- {
- //Firebug.Console.log(match[1]);
-
- var value = match[2].match(reOperaStackItemValue);
-
- if (value)
- {
- //Firebug.Console.log(value[1]);
- }
- //else
- // Firebug.Console.log(match[2]);
-
- //Firebug.Console.log("--------------------------");
- }
- }
- }
- /**/
- }
-
- //console.log(stack);
- //console.dir(frames);
- Firebug.Console.log({frames: frames}, context, "stackTrace", FirebugReps.StackTrace);
-
- traceRecursion--;
- };
-
- this.trace_ok = function()
- {
- var getFuncName = function getFuncName (f)
- {
- if (f.getName instanceof Function)
- return f.getName();
- if (f.name) // in FireFox, Function objects have a name property...
- return f.name;
-
- var name = f.toString().match(/function\s*([_$\w\d]*)/)[1];
- return name || "anonymous";
- };
-
- var wasVisited = function(fn)
- {
- for (var i=0, l=frames.length; i<l; i++)
- {
- if (frames[i].fn == fn)
- return true;
- }
-
- return false;
- };
-
- var frames = [];
-
- for (var fn = arguments.callee.caller; fn; fn = fn.caller)
- {
- if (wasVisited(fn)) break;
-
- var args = [];
-
- for (var i = 0, l = fn.arguments.length; i < l; ++i)
- {
- args.push({value: fn.arguments[i]});
- }
-
- frames.push({fn: fn, name: getFuncName(fn), args: args});
- }
-
- Firebug.Console.log({frames: frames}, context, "stackTrace", FirebugReps.StackTrace);
- };
-
- this.clear = function()
- {
- Firebug.Console.clear(context);
- };
-
- this.time = function(name, reset)
- {
- if (!name)
- return;
-
- var time = new Date().getTime();
-
- if (!this.timeCounters)
- this.timeCounters = {};
-
- var key = "KEY"+name.toString();
-
- if (!reset && this.timeCounters[key])
- return;
-
- this.timeCounters[key] = time;
- };
-
- this.timeEnd = function(name)
- {
- var time = new Date().getTime();
-
- if (!this.timeCounters)
- return;
-
- var key = "KEY"+name.toString();
-
- var timeCounter = this.timeCounters[key];
- if (timeCounter)
- {
- var diff = time - timeCounter;
- var label = name + ": " + diff + "ms";
-
- this.info(label);
-
- delete this.timeCounters[key];
- }
- return diff;
- };
-
- // These functions are over-ridden by commandLine
- this.evaluated = function(result, context)
- {
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("consoleInjector.FirebugConsoleHandler evalutated default called", result);
-
- Firebug.Console.log(result, context);
- };
- this.evaluateError = function(result, context)
- {
- Firebug.Console.log(result, context, "errorMessage");
- };
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- function logFormatted(args, className, linkToSource, noThrottle)
- {
- var sourceLink = linkToSource ? getStackLink() : null;
- return Firebug.Console.logFormatted(args, context, className, noThrottle, sourceLink);
- }
-
- function logAssert(category, args)
- {
- Firebug.Errors.increaseCount(context);
-
- if (!args || !args.length || args.length == 0)
- var msg = [FBL.$STR("Assertion")];
- else
- var msg = args[0];
-
- if (Firebug.errorStackTrace)
- {
- var trace = Firebug.errorStackTrace;
- delete Firebug.errorStackTrace;
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("logAssert trace from errorStackTrace", trace);
- }
- else if (msg.stack)
- {
- var trace = parseToStackTrace(msg.stack);
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("logAssert trace from msg.stack", trace);
- }
- else
- {
- var trace = getJSDUserStack();
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("logAssert trace from getJSDUserStack", trace);
- }
-
- var errorObject = new FBL.ErrorMessage(msg, (msg.fileName?msg.fileName:win.location), (msg.lineNumber?msg.lineNumber:0), "", category, context, trace);
-
-
- if (trace && trace.frames && trace.frames[0])
- errorObject.correctWithStackTrace(trace);
-
- errorObject.resetSource();
-
- var objects = errorObject;
- if (args.length > 1)
- {
- objects = [errorObject];
- for (var i = 1; i < args.length; i++)
- objects.push(args[i]);
- }
-
- var row = Firebug.Console.log(objects, context, "errorMessage", null, true); // noThrottle
- row.scrollIntoView();
- }
-
- function getComponentsStackDump()
- {
- // Starting with our stack, walk back to the user-level code
- var frame = Components.stack;
- var userURL = win.location.href.toString();
-
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("consoleInjector.getComponentsStackDump initial stack for userURL "+userURL, frame);
-
- // Drop frames until we get into user code.
- while (frame && FBL.isSystemURL(frame.filename) )
- frame = frame.caller;
-
- // Drop two more frames, the injected console function and firebugAppendConsole()
- if (frame)
- frame = frame.caller;
- if (frame)
- frame = frame.caller;
-
- if (FBTrace.DBG_CONSOLE)
- FBTrace.sysout("consoleInjector.getComponentsStackDump final stack for userURL "+userURL, frame);
-
- return frame;
- }
-
- function getStackLink()
- {
- // TODO: xxxpedro console2
- return;
- //return FBL.getFrameSourceLink(getComponentsStackDump());
- }
-
- function getJSDUserStack()
- {
- var trace = FBL.getCurrentStackTrace(context);
-
- var frames = trace ? trace.frames : null;
- if (frames && (frames.length > 0) )
- {
- var oldest = frames.length - 1; // 6 - 1 = 5
- for (var i = 0; i < frames.length; i++)
- {
- if (frames[oldest - i].href.indexOf("chrome:") == 0) break;
- var fn = frames[oldest - i].fn + "";
- if (fn && (fn.indexOf("_firebugEvalEvent") != -1) ) break; // command line
- }
- FBTrace.sysout("consoleInjector getJSDUserStack: "+frames.length+" oldest: "+oldest+" i: "+i+" i - oldest + 2: "+(i - oldest + 2), trace);
- trace.frames = trace.frames.slice(2 - i); // take the oldest frames, leave 2 behind they are injection code
-
- return trace;
- }
- else
- return "Firebug failed to get stack trace with any frames";
- }
-};
-
-// ************************************************************************************************
-// Register console namespace
-
-FBL.registerConsole = function()
-{
- var win = Env.browser.window;
- Firebug.Console.injector.install(win);
-};
-
-registerConsole();
-
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-
-// ************************************************************************************************
-// Globals
-
-var commandPrefix = ">>>";
-var reOpenBracket = /[\[\(\{]/;
-var reCloseBracket = /[\]\)\}]/;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var commandHistory = [];
-var commandPointer = -1;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var isAutoCompleting = null;
-var autoCompletePrefix = null;
-var autoCompleteExpr = null;
-var autoCompleteBuffer = null;
-var autoCompletePosition = null;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var fbCommandLine = null;
-var fbLargeCommandLine = null;
-var fbLargeCommandButtons = null;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var _completion =
-{
- window:
- [
- "console"
- ],
-
- document:
- [
- "getElementById",
- "getElementsByTagName"
- ]
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var _stack = function(command)
-{
- Firebug.context.persistedState.commandHistory.push(command);
- Firebug.context.persistedState.commandPointer =
- Firebug.context.persistedState.commandHistory.length;
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-// ************************************************************************************************
-// CommandLine
-
-Firebug.CommandLine = extend(Firebug.Module,
-{
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- element: null,
- isMultiLine: false,
- isActive: false,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- initialize: function(doc)
- {
- this.clear = bind(this.clear, this);
- this.enter = bind(this.enter, this);
-
- this.onError = bind(this.onError, this);
- this.onKeyDown = bind(this.onKeyDown, this);
- this.onMultiLineKeyDown = bind(this.onMultiLineKeyDown, this);
-
- addEvent(Firebug.browser.window, "error", this.onError);
- addEvent(Firebug.chrome.window, "error", this.onError);
- },
-
- shutdown: function(doc)
- {
- this.deactivate();
-
- removeEvent(Firebug.browser.window, "error", this.onError);
- removeEvent(Firebug.chrome.window, "error", this.onError);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- activate: function(multiLine, hideToggleIcon, onRun)
- {
- defineCommandLineAPI();
-
- Firebug.context.persistedState.commandHistory =
- Firebug.context.persistedState.commandHistory || [];
-
- Firebug.context.persistedState.commandPointer =
- Firebug.context.persistedState.commandPointer || -1;
-
- if (this.isActive)
- {
- if (this.isMultiLine == multiLine) return;
-
- this.deactivate();
- }
-
- fbCommandLine = $("fbCommandLine");
- fbLargeCommandLine = $("fbLargeCommandLine");
- fbLargeCommandButtons = $("fbLargeCommandButtons");
-
- if (multiLine)
- {
- onRun = onRun || this.enter;
-
- this.isMultiLine = true;
-
- this.element = fbLargeCommandLine;
-
- addEvent(this.element, "keydown", this.onMultiLineKeyDown);
-
- addEvent($("fbSmallCommandLineIcon"), "click", Firebug.chrome.hideLargeCommandLine);
-
- this.runButton = new Button({
- element: $("fbCommand_btRun"),
- owner: Firebug.CommandLine,
- onClick: onRun
- });
-
- this.runButton.initialize();
-
- this.clearButton = new Button({
- element: $("fbCommand_btClear"),
- owner: Firebug.CommandLine,
- onClick: this.clear
- });
-
- this.clearButton.initialize();
- }
- else
- {
- this.isMultiLine = false;
- this.element = fbCommandLine;
-
- if (!fbCommandLine)
- return;
-
- addEvent(this.element, "keydown", this.onKeyDown);
- }
-
- //Firebug.Console.log("activate", this.element);
-
- if (isOpera)
- fixOperaTabKey(this.element);
-
- if(this.lastValue)
- this.element.value = this.lastValue;
-
- this.isActive = true;
- },
-
- deactivate: function()
- {
- if (!this.isActive) return;
-
- //Firebug.Console.log("deactivate", this.element);
-
- this.isActive = false;
-
- this.lastValue = this.element.value;
-
- if (this.isMultiLine)
- {
- removeEvent(this.element, "keydown", this.onMultiLineKeyDown);
-
- removeEvent($("fbSmallCommandLineIcon"), "click", Firebug.chrome.hideLargeCommandLine);
-
- this.runButton.destroy();
- this.clearButton.destroy();
- }
- else
- {
- removeEvent(this.element, "keydown", this.onKeyDown);
- }
-
- this.element = null;
- delete this.element;
-
- fbCommandLine = null;
- fbLargeCommandLine = null;
- fbLargeCommandButtons = null;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- focus: function()
- {
- this.element.focus();
- },
-
- blur: function()
- {
- this.element.blur();
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- clear: function()
- {
- this.element.value = "";
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- evaluate: function(expr)
- {
- // TODO: need to register the API in console.firebug.commandLineAPI
- var api = "Firebug.CommandLine.API";
-
- var result = Firebug.context.evaluate(expr, "window", api, Firebug.Console.error);
-
- return result;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- enter: function()
- {
- var command = this.element.value;
-
- if (!command) return;
-
- _stack(command);
-
- Firebug.Console.log(commandPrefix + " " + stripNewLines(command),
- Firebug.browser, "command", FirebugReps.Text);
-
- var result = this.evaluate(command);
-
- Firebug.Console.log(result);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- prevCommand: function()
- {
- if (Firebug.context.persistedState.commandPointer > 0 &&
- Firebug.context.persistedState.commandHistory.length > 0)
- {
- this.element.value = Firebug.context.persistedState.commandHistory
- [--Firebug.context.persistedState.commandPointer];
- }
- },
-
- nextCommand: function()
- {
- var element = this.element;
-
- var limit = Firebug.context.persistedState.commandHistory.length -1;
- var i = Firebug.context.persistedState.commandPointer;
-
- if (i < limit)
- element.value = Firebug.context.persistedState.commandHistory
- [++Firebug.context.persistedState.commandPointer];
-
- else if (i == limit)
- {
- ++Firebug.context.persistedState.commandPointer;
- element.value = "";
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- autocomplete: function(reverse)
- {
- var element = this.element;
-
- var command = element.value;
- var offset = getExpressionOffset(command);
-
- var valBegin = offset ? command.substr(0, offset) : "";
- var val = command.substr(offset);
-
- var buffer, obj, objName, commandBegin, result, prefix;
-
- // if it is the beginning of the completion
- if(!isAutoCompleting)
- {
-
- // group1 - command begin
- // group2 - base object
- // group3 - property prefix
- var reObj = /(.*[^_$\w\d\.])?((?:[_$\w][_$\w\d]*\.)*)([_$\w][_$\w\d]*)?$/;
- var r = reObj.exec(val);
-
- // parse command
- if (r[1] || r[2] || r[3])
- {
- commandBegin = r[1] || "";
- objName = r[2] || "";
- prefix = r[3] || "";
- }
- else if (val == "")
- {
- commandBegin = objName = prefix = "";
- } else
- return;
-
- isAutoCompleting = true;
-
- // find base object
- if(objName == "")
- obj = window;
-
- else
- {
- objName = objName.replace(/\.$/, "");
-
- var n = objName.split(".");
- var target = window, o;
-
- for (var i=0, ni; ni = n[i]; i++)
- {
- if (o = target[ni])
- target = o;
-
- else
- {
- target = null;
- break;
- }
- }
- obj = target;
- }
-
- // map base object
- if(obj)
- {
- autoCompletePrefix = prefix;
- autoCompleteExpr = valBegin + commandBegin + (objName ? objName + "." : "");
- autoCompletePosition = -1;
-
- buffer = autoCompleteBuffer = isIE ?
- _completion[objName || "window"] || [] : [];
-
- for(var p in obj)
- buffer.push(p);
- }
-
- // if it is the continuation of the last completion
- } else
- buffer = autoCompleteBuffer;
-
- if (buffer)
- {
- prefix = autoCompletePrefix;
-
- var diff = reverse ? -1 : 1;
-
- for(var i=autoCompletePosition+diff, l=buffer.length, bi; i>=0 && i<l; i+=diff)
- {
- bi = buffer[i];
-
- if (bi.indexOf(prefix) == 0)
- {
- autoCompletePosition = i;
- result = bi;
- break;
- }
- }
- }
-
- if (result)
- element.value = autoCompleteExpr + result;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- setMultiLine: function(multiLine)
- {
- if (multiLine == this.isMultiLine) return;
-
- this.activate(multiLine);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- onError: function(msg, href, lineNo)
- {
- href = href || "";
-
- var lastSlash = href.lastIndexOf("/");
- var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);
- var html = [
- '<span class="errorMessage">', msg, '</span>',
- '<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>'
- ];
-
- // TODO: xxxpedro ajust to Console2
- //Firebug.Console.writeRow(html, "error");
- },
-
- onKeyDown: function(e)
- {
- e = e || event;
-
- var code = e.keyCode;
-
- /*tab, shift, control, alt*/
- if (code != 9 && code != 16 && code != 17 && code != 18)
- {
- isAutoCompleting = false;
- }
-
- if (code == 13 /* enter */)
- {
- this.enter();
- this.clear();
- }
- else if (code == 27 /* ESC */)
- {
- setTimeout(this.clear, 0);
- }
- else if (code == 38 /* up */)
- {
- this.prevCommand();
- }
- else if (code == 40 /* down */)
- {
- this.nextCommand();
- }
- else if (code == 9 /* tab */)
- {
- this.autocomplete(e.shiftKey);
- }
- else
- return;
-
- cancelEvent(e, true);
- return false;
- },
-
- onMultiLineKeyDown: function(e)
- {
- e = e || event;
-
- var code = e.keyCode;
-
- if (code == 13 /* enter */ && e.ctrlKey)
- {
- this.enter();
- }
- }
-});
-
-Firebug.registerModule(Firebug.CommandLine);
-
-
-// ************************************************************************************************
-//
-
-function getExpressionOffset(command)
-{
- // XXXjoe This is kind of a poor-man's JavaScript parser - trying
- // to find the start of the expression that the cursor is inside.
- // Not 100% fool proof, but hey...
-
- var bracketCount = 0;
-
- var start = command.length-1;
- for (; start >= 0; --start)
- {
- var c = command[start];
- if ((c == "," || c == ";" || c == " ") && !bracketCount)
- break;
- if (reOpenBracket.test(c))
- {
- if (bracketCount)
- --bracketCount;
- else
- break;
- }
- else if (reCloseBracket.test(c))
- ++bracketCount;
- }
-
- return start + 1;
-}
-
-// ************************************************************************************************
-// CommandLine API
-
-var CommandLineAPI =
-{
- $: function(id)
- {
- return Firebug.browser.document.getElementById(id);
- },
-
- $$: function(selector, context)
- {
- context = context || Firebug.browser.document;
- return Firebug.Selector ?
- Firebug.Selector(selector, context) :
- Firebug.Console.error("Firebug.Selector module not loaded.");
- },
-
- $0: null,
-
- $1: null,
-
- dir: function(o)
- {
- Firebug.Console.log(o, Firebug.context, "dir", Firebug.DOMPanel.DirTable);
- },
-
- dirxml: function(o)
- {
- ///if (o instanceof Window)
- if (instanceOf(o, "Window"))
- o = o.document.documentElement;
- ///else if (o instanceof Document)
- else if (instanceOf(o, "Document"))
- o = o.documentElement;
-
- Firebug.Console.log(o, Firebug.context, "dirxml", Firebug.HTMLPanel.SoloElement);
- }
-};
-
-// ************************************************************************************************
-
-var defineCommandLineAPI = function defineCommandLineAPI()
-{
- Firebug.CommandLine.API = {};
- for (var m in CommandLineAPI)
- if (!Env.browser.window[m])
- Firebug.CommandLine.API[m] = CommandLineAPI[m];
-
- var stack = FirebugChrome.htmlSelectionStack;
- if (stack)
- {
- Firebug.CommandLine.API.$0 = stack[0];
- Firebug.CommandLine.API.$1 = stack[1];
- }
-};
-
-// ************************************************************************************************
-}});
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-// ************************************************************************************************
-// Globals
-
-var ElementCache = Firebug.Lite.Cache.Element;
-var cacheID = Firebug.Lite.Cache.ID;
-
-var ignoreHTMLProps =
-{
- // ignores the attributes injected by Sizzle, otherwise it will
- // be visible on IE (when enumerating element.attributes)
- sizcache: 1,
- sizset: 1
-};
-
-if (Firebug.ignoreFirebugElements)
- // ignores also the cache property injected by firebug
- ignoreHTMLProps[cacheID] = 1;
-
-
-// ************************************************************************************************
-// HTML Module
-
-Firebug.HTML = extend(Firebug.Module,
-{
- appendTreeNode: function(nodeArray, html)
- {
- var reTrim = /^\s+|\s+$/g;
-
- if (!nodeArray.length) nodeArray = [nodeArray];
-
- for (var n=0, node; node=nodeArray[n]; n++)
- {
- if (node.nodeType == 1)
- {
- if (Firebug.ignoreFirebugElements && node.firebugIgnore) continue;
-
- var uid = ElementCache(node);
- var child = node.childNodes;
- var childLength = child.length;
-
- var nodeName = node.nodeName.toLowerCase();
-
- var nodeVisible = isVisible(node);
-
- var hasSingleTextChild = childLength == 1 && node.firstChild.nodeType == 3 &&
- nodeName != "script" && nodeName != "style";
-
- var nodeControl = !hasSingleTextChild && childLength > 0 ?
- ('<div class="nodeControl"></div>') : '';
-
- // FIXME xxxpedro remove this
- //var isIE = false;
-
- if(isIE && nodeControl)
- html.push(nodeControl);
-
- if (typeof uid != 'undefined')
- html.push(
- '<div class="objectBox-element" ',
- 'id="', uid,
- '">',
- !isIE && nodeControl ? nodeControl: "",
- '<span ',
- cacheID,
- '="', uid,
- '" class="nodeBox',
- nodeVisible ? "" : " nodeHidden",
- '">&lt;<span class="nodeTag">', nodeName, '</span>'
- );
- else
- html.push(
- '<div class="objectBox-element"><span class="nodeBox',
- nodeVisible ? "" : " nodeHidden",
- '">&lt;<span class="nodeTag">',
- nodeName, '</span>'
- );
-
- for (var i = 0; i < node.attributes.length; ++i)
- {
- var attr = node.attributes[i];
- if (!attr.specified ||
- // Issue 4432: Firebug Lite: HTML is mixed-up with functions
- // The problem here is that expando properties added to DOM elements in
- // IE < 9 will behave like DOM attributes and so they'll show up when
- // looking at element.attributes list.
- isIE && (browserVersion-0<9) && typeof attr.nodeValue != "string" ||
- Firebug.ignoreFirebugElements && ignoreHTMLProps.hasOwnProperty(attr.nodeName))
- continue;
-
- var name = attr.nodeName.toLowerCase();
- var value = name == "style" ? formatStyles(node.style.cssText) : attr.nodeValue;
-
- html.push('&nbsp;<span class="nodeName">', name,
- '</span>=&quot;<span class="nodeValue">', escapeHTML(value),
- '</span>&quot;');
- }
-
- /*
- // source code nodes
- if (nodeName == 'script' || nodeName == 'style')
- {
-
- if(document.all){
- var src = node.innerHTML+'\n';
-
- }else {
- var src = '\n'+node.innerHTML+'\n';
- }
-
- var match = src.match(/\n/g);
- var num = match ? match.length : 0;
- var s = [], sl = 0;
-
- for(var c=1; c<num; c++){
- s[sl++] = '<div line="'+c+'">' + c + '</div>';
- }
-
- html.push('&gt;</div><div class="nodeGroup"><div class="nodeChildren"><div class="lineNo">',
- s.join(''),
- '</div><pre class="nodeCode">',
- escapeHTML(src),
- '</pre>',
- '</div><div class="objectBox-element">&lt;/<span class="nodeTag">',
- nodeName,
- '</span>&gt;</div>',
- '</div>'
- );
-
-
- }/**/
-
- // Just a single text node child
- if (hasSingleTextChild)
- {
- var value = child[0].nodeValue.replace(reTrim, '');
- if(value)
- {
- html.push(
- '&gt;<span class="nodeText">',
- escapeHTML(value),
- '</span>&lt;/<span class="nodeTag">',
- nodeName,
- '</span>&gt;</span></div>'
- );
- }
- else
- html.push('/&gt;</span></div>'); // blank text, print as childless node
-
- }
- else if (childLength > 0)
- {
- html.push('&gt;</span></div>');
- }
- else
- html.push('/&gt;</span></div>');
-
- }
- else if (node.nodeType == 3)
- {
- if ( node.parentNode && ( node.parentNode.nodeName.toLowerCase() == "script" ||
- node.parentNode.nodeName.toLowerCase() == "style" ) )
- {
- var value = node.nodeValue.replace(reTrim, '');
-
- if(isIE){
- var src = value+'\n';
-
- }else {
- var src = '\n'+value+'\n';
- }
-
- var match = src.match(/\n/g);
- var num = match ? match.length : 0;
- var s = [], sl = 0;
-
- for(var c=1; c<num; c++){
- s[sl++] = '<div line="'+c+'">' + c + '</div>';
- }
-
- html.push('<div class="lineNo">',
- s.join(''),
- '</div><pre class="sourceCode">',
- escapeHTML(src),
- '</pre>'
- );
-
- }
- else
- {
- var value = node.nodeValue.replace(reTrim, '');
- if (value)
- html.push('<div class="nodeText">', escapeHTML(value),'</div>');
- }
- }
- }
- },
-
- appendTreeChildren: function(treeNode)
- {
- var doc = Firebug.chrome.document;
- var uid = treeNode.id;
- var parentNode = ElementCache.get(uid);
-
- if (parentNode.childNodes.length == 0) return;
-
- var treeNext = treeNode.nextSibling;
- var treeParent = treeNode.parentNode;
-
- // FIXME xxxpedro remove this
- //var isIE = false;
- var control = isIE ? treeNode.previousSibling : treeNode.firstChild;
- control.className = 'nodeControl nodeMaximized';
-
- var html = [];
- var children = doc.createElement("div");
- children.className = "nodeChildren";
- this.appendTreeNode(parentNode.childNodes, html);
- children.innerHTML = html.join("");
-
- treeParent.insertBefore(children, treeNext);
-
- var closeElement = doc.createElement("div");
- closeElement.className = "objectBox-element";
- closeElement.innerHTML = '&lt;/<span class="nodeTag">' +
- parentNode.nodeName.toLowerCase() + '&gt;</span>';
-
- treeParent.insertBefore(closeElement, treeNext);
-
- },
-
- removeTreeChildren: function(treeNode)
- {
- var children = treeNode.nextSibling;
- var closeTag = children.nextSibling;
-
- // FIXME xxxpedro remove this
- //var isIE = false;
- var control = isIE ? treeNode.previousSibling : treeNode.firstChild;
- control.className = 'nodeControl';
-
- children.parentNode.removeChild(children);
- closeTag.parentNode.removeChild(closeTag);
- },
-
- isTreeNodeVisible: function(id)
- {
- return $(id);
- },
-
- select: function(el)
- {
- var id = el && ElementCache(el);
- if (id)
- this.selectTreeNode(id);
- },
-
- selectTreeNode: function(id)
- {
- id = ""+id;
- var node, stack = [];
- while(id && !this.isTreeNodeVisible(id))
- {
- stack.push(id);
-
- var node = ElementCache.get(id).parentNode;
-
- if (node)
- id = ElementCache(node);
- else
- break;
- }
-
- stack.push(id);
-
- while(stack.length > 0)
- {
- id = stack.pop();
- node = $(id);
-
- if (stack.length > 0 && ElementCache.get(id).childNodes.length > 0)
- this.appendTreeChildren(node);
- }
-
- selectElement(node);
-
- // TODO: xxxpedro
- if (fbPanel1)
- fbPanel1.scrollTop = Math.round(node.offsetTop - fbPanel1.clientHeight/2);
- }
-
-});
-
-Firebug.registerModule(Firebug.HTML);
-
-// ************************************************************************************************
-// HTML Panel
-
-function HTMLPanel(){};
-
-HTMLPanel.prototype = extend(Firebug.Panel,
-{
- name: "HTML",
- title: "HTML",
-
- options: {
- hasSidePanel: true,
- //hasToolButtons: true,
- isPreRendered: !Firebug.flexChromeEnabled /* FIXME xxxpedro chromenew */,
- innerHTMLSync: true
- },
-
- create: function(){
- Firebug.Panel.create.apply(this, arguments);
-
- this.panelNode.style.padding = "4px 3px 1px 15px";
- this.panelNode.style.minWidth = "500px";
-
- if (Env.Options.enablePersistent || Firebug.chrome.type != "popup")
- this.createUI();
-
- if(this.sidePanelBar && !this.sidePanelBar.selectedPanel)
- {
- this.sidePanelBar.selectPanel("css");
- }
- },
-
- destroy: function()
- {
- selectedElement = null;
- fbPanel1 = null;
-
- selectedSidePanelTS = null;
- selectedSidePanelTimer = null;
-
- Firebug.Panel.destroy.apply(this, arguments);
- },
-
- createUI: function()
- {
- var rootNode = Firebug.browser.document.documentElement;
- var html = [];
- Firebug.HTML.appendTreeNode(rootNode, html);
-
- this.panelNode.innerHTML = html.join("");
- },
-
- initialize: function()
- {
- Firebug.Panel.initialize.apply(this, arguments);
- addEvent(this.panelNode, 'click', Firebug.HTML.onTreeClick);
-
- fbPanel1 = $("fbPanel1");
-
- if(!selectedElement)
- {
- Firebug.context.persistedState.selectedHTMLElementId =
- Firebug.context.persistedState.selectedHTMLElementId &&
- ElementCache.get(Firebug.context.persistedState.selectedHTMLElementId) ?
- Firebug.context.persistedState.selectedHTMLElementId :
- ElementCache(Firebug.browser.document.body);
-
- Firebug.HTML.selectTreeNode(Firebug.context.persistedState.selectedHTMLElementId);
- }
-
- // TODO: xxxpedro
- addEvent(fbPanel1, 'mousemove', Firebug.HTML.onListMouseMove);
- addEvent($("fbContent"), 'mouseout', Firebug.HTML.onListMouseMove);
- addEvent(Firebug.chrome.node, 'mouseout', Firebug.HTML.onListMouseMove);
- },
-
- shutdown: function()
- {
- // TODO: xxxpedro
- removeEvent(fbPanel1, 'mousemove', Firebug.HTML.onListMouseMove);
- removeEvent($("fbContent"), 'mouseout', Firebug.HTML.onListMouseMove);
- removeEvent(Firebug.chrome.node, 'mouseout', Firebug.HTML.onListMouseMove);
-
- removeEvent(this.panelNode, 'click', Firebug.HTML.onTreeClick);
-
- fbPanel1 = null;
-
- Firebug.Panel.shutdown.apply(this, arguments);
- },
-
- reattach: function()
- {
- // TODO: panel reattach
- if(Firebug.context.persistedState.selectedHTMLElementId)
- Firebug.HTML.selectTreeNode(Firebug.context.persistedState.selectedHTMLElementId);
- },
-
- updateSelection: function(object)
- {
- var id = ElementCache(object);
-
- if (id)
- {
- Firebug.HTML.selectTreeNode(id);
- }
- }
-});
-
-Firebug.registerPanel(HTMLPanel);
-
-// ************************************************************************************************
-
-var formatStyles = function(styles)
-{
- return isIE ?
- // IE return CSS property names in upper case, so we need to convert them
- styles.replace(/([^\s]+)\s*:/g, function(m,g){return g.toLowerCase()+":";}) :
- // other browsers are just fine
- styles;
-};
-
-// ************************************************************************************************
-
-var selectedElement = null;
-var fbPanel1 = null;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-var selectedSidePanelTS, selectedSidePanelTimer;
-
-var selectElement= function selectElement(e)
-{
- if (e != selectedElement)
- {
- if (selectedElement)
- selectedElement.className = "objectBox-element";
-
- e.className = e.className + " selectedElement";
-
- if (FBL.isFirefox)
- e.style.MozBorderRadius = "2px";
-
- else if (FBL.isSafari)
- e.style.WebkitBorderRadius = "2px";
-
- e.style.borderRadius = "2px";
-
- selectedElement = e;
-
- Firebug.context.persistedState.selectedHTMLElementId = e.id;
-
- var target = ElementCache.get(e.id);
- var sidePanelBar = Firebug.chrome.getPanel("HTML").sidePanelBar;
- var selectedSidePanel = sidePanelBar ? sidePanelBar.selectedPanel : null;
-
- var stack = FirebugChrome.htmlSelectionStack;
-
- stack.unshift(target);
-
- if (stack.length > 2)
- stack.pop();
-
- var lazySelect = function()
- {
- selectedSidePanelTS = new Date().getTime();
-
- if (selectedSidePanel)
- selectedSidePanel.select(target, true);
- };
-
- if (selectedSidePanelTimer)
- {
- clearTimeout(selectedSidePanelTimer);
- selectedSidePanelTimer = null;
- }
-
- if (new Date().getTime() - selectedSidePanelTS > 100)
- setTimeout(lazySelect, 0);
- else
- selectedSidePanelTimer = setTimeout(lazySelect, 150);
- }
-};
-
-
-// ************************************************************************************************
-// *** TODO: REFACTOR **************************************************************************
-// ************************************************************************************************
-Firebug.HTML.onTreeClick = function (e)
-{
- e = e || event;
- var targ;
-
- if (e.target) targ = e.target;
- else if (e.srcElement) targ = e.srcElement;
- if (targ.nodeType == 3) // defeat Safari bug
- targ = targ.parentNode;
-
-
- if (targ.className.indexOf('nodeControl') != -1 || targ.className == 'nodeTag')
- {
- // FIXME xxxpedro remove this
- //var isIE = false;
-
- if(targ.className == 'nodeTag')
- {
- var control = isIE ? (targ.parentNode.previousSibling || targ) :
- (targ.parentNode.previousSibling || targ);
-
- selectElement(targ.parentNode.parentNode);
-
- if (control.className.indexOf('nodeControl') == -1)
- return;
-
- } else
- control = targ;
-
- FBL.cancelEvent(e);
-
- var treeNode = isIE ? control.nextSibling : control.parentNode;
-
- //FBL.Firebug.Console.log(treeNode);
-
- if (control.className.indexOf(' nodeMaximized') != -1) {
- FBL.Firebug.HTML.removeTreeChildren(treeNode);
- } else {
- FBL.Firebug.HTML.appendTreeChildren(treeNode);
- }
- }
- else if (targ.className == 'nodeValue' || targ.className == 'nodeName')
- {
- /*
- var input = FBL.Firebug.chrome.document.getElementById('treeInput');
-
- input.style.display = "block";
- input.style.left = targ.offsetLeft + 'px';
- input.style.top = FBL.topHeight + targ.offsetTop - FBL.fbPanel1.scrollTop + 'px';
- input.style.width = targ.offsetWidth + 6 + 'px';
- input.value = targ.textContent || targ.innerText;
- input.focus();
- /**/
- }
-};
-
-function onListMouseOut(e)
-{
- e = e || event || window;
- var targ;
-
- if (e.target) targ = e.target;
- else if (e.srcElement) targ = e.srcElement;
- if (targ.nodeType == 3) // defeat Safari bug
- targ = targ.parentNode;
-
- if (hasClass(targ, "fbPanel")) {
- FBL.Firebug.Inspector.hideBoxModel();
- hoverElement = null;
- }
-};
-
-var hoverElement = null;
-var hoverElementTS = 0;
-
-Firebug.HTML.onListMouseMove = function onListMouseMove(e)
-{
- try
- {
- e = e || event || window;
- var targ;
-
- if (e.target) targ = e.target;
- else if (e.srcElement) targ = e.srcElement;
- if (targ.nodeType == 3) // defeat Safari bug
- targ = targ.parentNode;
-
- var found = false;
- while (targ && !found) {
- if (!/\snodeBox\s|\sobjectBox-selector\s/.test(" " + targ.className + " "))
- targ = targ.parentNode;
- else
- found = true;
- }
-
- if (!targ)
- {
- FBL.Firebug.Inspector.hideBoxModel();
- hoverElement = null;
- return;
- }
-
- /*
- if (typeof targ.attributes[cacheID] == 'undefined') return;
-
- var uid = targ.attributes[cacheID];
- if (!uid) return;
- /**/
-
- if (typeof targ.attributes[cacheID] == 'undefined') return;
-
- var uid = targ.attributes[cacheID];
- if (!uid) return;
-
- var el = ElementCache.get(uid.value);
-
- var nodeName = el.nodeName.toLowerCase();
-
- if (FBL.isIE && " meta title script link ".indexOf(" "+nodeName+" ") != -1)
- return;
-
- if (!/\snodeBox\s|\sobjectBox-selector\s/.test(" " + targ.className + " ")) return;
-
- if (el.id == "FirebugUI" || " html head body br script link iframe ".indexOf(" "+nodeName+" ") != -1) {
- FBL.Firebug.Inspector.hideBoxModel();
- hoverElement = null;
- return;
- }
-
- if ((new Date().getTime() - hoverElementTS > 40) && hoverElement != el) {
- hoverElementTS = new Date().getTime();
- hoverElement = el;
- FBL.Firebug.Inspector.drawBoxModel(el);
- }
- }
- catch(E)
- {
- }
-};
-
-
-// ************************************************************************************************
-
-Firebug.Reps = {
-
- appendText: function(object, html)
- {
- html.push(escapeHTML(objectToString(object)));
- },
-
- appendNull: function(object, html)
- {
- html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>');
- },
-
- appendString: function(object, html)
- {
- html.push('<span class="objectBox-string">&quot;', escapeHTML(objectToString(object)),
- '&quot;</span>');
- },
-
- appendInteger: function(object, html)
- {
- html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
- },
-
- appendFloat: function(object, html)
- {
- html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
- },
-
- appendFunction: function(object, html)
- {
- var reName = /function ?(.*?)\(/;
- var m = reName.exec(objectToString(object));
- var name = m && m[1] ? m[1] : "function";
- html.push('<span class="objectBox-function">', escapeHTML(name), '()</span>');
- },
-
- appendObject: function(object, html)
- {
- /*
- var rep = Firebug.getRep(object);
- var outputs = [];
-
- rep.tag.tag.compile();
-
- var str = rep.tag.renderHTML({object: object}, outputs);
- html.push(str);
- /**/
-
- try
- {
- if (object == undefined)
- this.appendNull("undefined", html);
- else if (object == null)
- this.appendNull("null", html);
- else if (typeof object == "string")
- this.appendString(object, html);
- else if (typeof object == "number")
- this.appendInteger(object, html);
- else if (typeof object == "boolean")
- this.appendInteger(object, html);
- else if (typeof object == "function")
- this.appendFunction(object, html);
- else if (object.nodeType == 1)
- this.appendSelector(object, html);
- else if (typeof object == "object")
- {
- if (typeof object.length != "undefined")
- this.appendArray(object, html);
- else
- this.appendObjectFormatted(object, html);
- }
- else
- this.appendText(object, html);
- }
- catch (exc)
- {
- }
- /**/
- },
-
- appendObjectFormatted: function(object, html)
- {
- var text = objectToString(object);
- var reObject = /\[object (.*?)\]/;
-
- var m = reObject.exec(text);
- html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>');
- },
-
- appendSelector: function(object, html)
- {
- var uid = ElementCache(object);
- var uidString = uid ? [cacheID, '="', uid, '"'].join("") : "";
-
- html.push('<span class="objectBox-selector"', uidString, '>');
-
- html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>');
- if (object.id)
- html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>');
- if (object.className)
- html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>');
-
- html.push('</span>');
- },
-
- appendNode: function(node, html)
- {
- if (node.nodeType == 1)
- {
- var uid = ElementCache(node);
- var uidString = uid ? [cacheID, '="', uid, '"'].join("") : "";
-
- html.push(
- '<div class="objectBox-element"', uidString, '">',
- '<span ', cacheID, '="', uid, '" class="nodeBox">',
- '&lt;<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>');
-
- for (var i = 0; i < node.attributes.length; ++i)
- {
- var attr = node.attributes[i];
- if (!attr.specified || attr.nodeName == cacheID)
- continue;
-
- var name = attr.nodeName.toLowerCase();
- var value = name == "style" ? node.style.cssText : attr.nodeValue;
-
- html.push('&nbsp;<span class="nodeName">', name,
- '</span>=&quot;<span class="nodeValue">', escapeHTML(value),
- '</span>&quot;');
- }
-
- if (node.firstChild)
- {
- html.push('&gt;</div><div class="nodeChildren">');
-
- for (var child = node.firstChild; child; child = child.nextSibling)
- this.appendNode(child, html);
-
- html.push('</div><div class="objectBox-element">&lt;/<span class="nodeTag">',
- node.nodeName.toLowerCase(), '&gt;</span></span></div>');
- }
- else
- html.push('/&gt;</span></div>');
- }
- else if (node.nodeType == 3)
- {
- var value = trim(node.nodeValue);
- if (value)
- html.push('<div class="nodeText">', escapeHTML(value),'</div>');
- }
- },
-
- appendArray: function(object, html)
- {
- html.push('<span class="objectBox-array"><b>[</b> ');
-
- for (var i = 0, l = object.length, obj; i < l; ++i)
- {
- this.appendObject(object[i], html);
-
- if (i < l-1)
- html.push(', ');
- }
-
- html.push(' <b>]</b></span>');
- }
-
-};
-
-
-
-// ************************************************************************************************
-}});
-
-/* See license.txt for terms of usage */
-
-/*
-
-Hack:
-Firebug.chrome.currentPanel = Firebug.chrome.selectedPanel;
-Firebug.showInfoTips = true;
-Firebug.InfoTip.initializeBrowser(Firebug.chrome);
-
-/**/
-
-FBL.ns(function() { with (FBL) {
-
-// ************************************************************************************************
-// Constants
-
-var maxWidth = 100, maxHeight = 80;
-var infoTipMargin = 10;
-var infoTipWindowPadding = 25;
-
-// ************************************************************************************************
-
-Firebug.InfoTip = extend(Firebug.Module,
-{
- dispatchName: "infoTip",
- tags: domplate(
- {
- infoTipTag: DIV({"class": "infoTip"}),
-
- colorTag:
- DIV({style: "background: $rgbValue; width: 100px; height: 40px"}, "&nbsp;"),
-
- imgTag:
- DIV({"class": "infoTipImageBox infoTipLoading"},
- IMG({"class": "infoTipImage", src: "$urlValue", repeat: "$repeat",
- onload: "$onLoadImage"}),
- IMG({"class": "infoTipBgImage", collapsed: true, src: "blank.gif"}),
- DIV({"class": "infoTipCaption"})
- ),
-
- onLoadImage: function(event)
- {
- var img = event.currentTarget || event.srcElement;
- ///var bgImg = img.nextSibling;
- ///if (!bgImg)
- /// return; // Sometimes gets called after element is dead
-
- ///var caption = bgImg.nextSibling;
- var innerBox = img.parentNode;
-
- /// TODO: xxxpedro infoTip hack
- var caption = getElementByClass(innerBox, "infoTipCaption");
- var bgImg = getElementByClass(innerBox, "infoTipBgImage");
- if (!bgImg)
- return; // Sometimes gets called after element is dead
-
- // TODO: xxxpedro infoTip IE and timing issue
- // TODO: use offline document to avoid flickering
- if (isIE)
- removeClass(innerBox, "infoTipLoading");
-
- var updateInfoTip = function(){
-
- var w = img.naturalWidth || img.width || 10,
- h = img.naturalHeight || img.height || 10;
-
- var repeat = img.getAttribute("repeat");
-
- if (repeat == "repeat-x" || (w == 1 && h > 1))
- {
- collapse(img, true);
- collapse(bgImg, false);
- bgImg.style.background = "url(" + img.src + ") repeat-x";
- bgImg.style.width = maxWidth + "px";
- if (h > maxHeight)
- bgImg.style.height = maxHeight + "px";
- else
- bgImg.style.height = h + "px";
- }
- else if (repeat == "repeat-y" || (h == 1 && w > 1))
- {
- collapse(img, true);
- collapse(bgImg, false);
- bgImg.style.background = "url(" + img.src + ") repeat-y";
- bgImg.style.height = maxHeight + "px";
- if (w > maxWidth)
- bgImg.style.width = maxWidth + "px";
- else
- bgImg.style.width = w + "px";
- }
- else if (repeat == "repeat" || (w == 1 && h == 1))
- {
- collapse(img, true);
- collapse(bgImg, false);
- bgImg.style.background = "url(" + img.src + ") repeat";
- bgImg.style.width = maxWidth + "px";
- bgImg.style.height = maxHeight + "px";
- }
- else
- {
- if (w > maxWidth || h > maxHeight)
- {
- if (w > h)
- {
- img.style.width = maxWidth + "px";
- img.style.height = Math.round((h / w) * maxWidth) + "px";
- }
- else
- {
- img.style.width = Math.round((w / h) * maxHeight) + "px";
- img.style.height = maxHeight + "px";
- }
- }
- }
-
- //caption.innerHTML = $STRF("Dimensions", [w, h]);
- caption.innerHTML = $STRF(w + " x " + h);
-
-
- };
-
- if (isIE)
- setTimeout(updateInfoTip, 0);
- else
- {
- updateInfoTip();
- removeClass(innerBox, "infoTipLoading");
- }
-
- ///
- }
-
- /*
- /// onLoadImage original
- onLoadImage: function(event)
- {
- var img = event.currentTarget;
- var bgImg = img.nextSibling;
- if (!bgImg)
- return; // Sometimes gets called after element is dead
-
- var caption = bgImg.nextSibling;
- var innerBox = img.parentNode;
-
- var w = img.naturalWidth, h = img.naturalHeight;
- var repeat = img.getAttribute("repeat");
-
- if (repeat == "repeat-x" || (w == 1 && h > 1))
- {
- collapse(img, true);
- collapse(bgImg, false);
- bgImg.style.background = "url(" + img.src + ") repeat-x";
- bgImg.style.width = maxWidth + "px";
- if (h > maxHeight)
- bgImg.style.height = maxHeight + "px";
- else
- bgImg.style.height = h + "px";
- }
- else if (repeat == "repeat-y" || (h == 1 && w > 1))
- {
- collapse(img, true);
- collapse(bgImg, false);
- bgImg.style.background = "url(" + img.src + ") repeat-y";
- bgImg.style.height = maxHeight + "px";
- if (w > maxWidth)
- bgImg.style.width = maxWidth + "px";
- else
- bgImg.style.width = w + "px";
- }
- else if (repeat == "repeat" || (w == 1 && h == 1))
- {
- collapse(img, true);
- collapse(bgImg, false);
- bgImg.style.background = "url(" + img.src + ") repeat";
- bgImg.style.width = maxWidth + "px";
- bgImg.style.height = maxHeight + "px";
- }
- else
- {
- if (w > maxWidth || h > maxHeight)
- {
- if (w > h)
- {
- img.style.width = maxWidth + "px";
- img.style.height = Math.round((h / w) * maxWidth) + "px";
- }
- else
- {
- img.style.width = Math.round((w / h) * maxHeight) + "px";
- img.style.height = maxHeight + "px";
- }
- }
- }
-
- caption.innerHTML = $STRF("Dimensions", [w, h]);
-
- removeClass(innerBox, "infoTipLoading");
- }
- /**/
-
- }),
-
- initializeBrowser: function(browser)
- {
- browser.onInfoTipMouseOut = bind(this.onMouseOut, this, browser);
- browser.onInfoTipMouseMove = bind(this.onMouseMove, this, browser);
-
- ///var doc = browser.contentDocument;
- var doc = browser.document;
- if (!doc)
- return;
-
- ///doc.addEventListener("mouseover", browser.onInfoTipMouseMove, true);
- ///doc.addEventListener("mouseout", browser.onInfoTipMouseOut, true);
- ///doc.addEventListener("mousemove", browser.onInfoTipMouseMove, true);
- addEvent(doc, "mouseover", browser.onInfoTipMouseMove);
- addEvent(doc, "mouseout", browser.onInfoTipMouseOut);
- addEvent(doc, "mousemove", browser.onInfoTipMouseMove);
-
- return browser.infoTip = this.tags.infoTipTag.append({}, getBody(doc));
- },
-
- uninitializeBrowser: function(browser)
- {
- if (browser.infoTip)
- {
- ///var doc = browser.contentDocument;
- var doc = browser.document;
- ///doc.removeEventListener("mouseover", browser.onInfoTipMouseMove, true);
- ///doc.removeEventListener("mouseout", browser.onInfoTipMouseOut, true);
- ///doc.removeEventListener("mousemove", browser.onInfoTipMouseMove, true);
- removeEvent(doc, "mouseover", browser.onInfoTipMouseMove);
- removeEvent(doc, "mouseout", browser.onInfoTipMouseOut);
- removeEvent(doc, "mousemove", browser.onInfoTipMouseMove);
-
- browser.infoTip.parentNode.removeChild(browser.infoTip);
- delete browser.infoTip;
- delete browser.onInfoTipMouseMove;
- }
- },
-
- showInfoTip: function(infoTip, panel, target, x, y, rangeParent, rangeOffset)
- {
- if (!Firebug.showInfoTips)
- return;
-
- var scrollParent = getOverflowParent(target);
- var scrollX = x + (scrollParent ? scrollParent.scrollLeft : 0);
-
- if (panel.showInfoTip(infoTip, target, scrollX, y, rangeParent, rangeOffset))
- {
- var htmlElt = infoTip.ownerDocument.documentElement;
- var panelWidth = htmlElt.clientWidth;
- var panelHeight = htmlElt.clientHeight;
-
- if (x+infoTip.offsetWidth+infoTipMargin > panelWidth)
- {
- infoTip.style.left = Math.max(0, panelWidth-(infoTip.offsetWidth+infoTipMargin)) + "px";
- infoTip.style.right = "auto";
- }
- else
- {
- infoTip.style.left = (x+infoTipMargin) + "px";
- infoTip.style.right = "auto";
- }
-
- if (y+infoTip.offsetHeight+infoTipMargin > panelHeight)
- {
- infoTip.style.top = Math.max(0, panelHeight-(infoTip.offsetHeight+infoTipMargin)) + "px";
- infoTip.style.bottom = "auto";
- }
- else
- {
- infoTip.style.top = (y+infoTipMargin) + "px";
- infoTip.style.bottom = "auto";
- }
-
- if (FBTrace.DBG_INFOTIP)
- FBTrace.sysout("infotip.showInfoTip; top: " + infoTip.style.top +
- ", left: " + infoTip.style.left + ", bottom: " + infoTip.style.bottom +
- ", right:" + infoTip.style.right + ", offsetHeight: " + infoTip.offsetHeight +
- ", offsetWidth: " + infoTip.offsetWidth +
- ", x: " + x + ", panelWidth: " + panelWidth +
- ", y: " + y + ", panelHeight: " + panelHeight);
-
- infoTip.setAttribute("active", "true");
- }
- else
- this.hideInfoTip(infoTip);
- },
-
- hideInfoTip: function(infoTip)
- {
- if (infoTip)
- infoTip.removeAttribute("active");
- },
-
- onMouseOut: function(event, browser)
- {
- if (!event.relatedTarget)
- this.hideInfoTip(browser.infoTip);
- },
-
- onMouseMove: function(event, browser)
- {
- // Ignore if the mouse is moving over the existing info tip.
- if (getAncestorByClass(event.target, "infoTip"))
- return;
-
- if (browser.currentPanel)
- {
- var x = event.clientX, y = event.clientY, target = event.target || event.srcElement;
- this.showInfoTip(browser.infoTip, browser.currentPanel, target, x, y, event.rangeParent, event.rangeOffset);
- }
- else
- this.hideInfoTip(browser.infoTip);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- populateColorInfoTip: function(infoTip, color)
- {
- this.tags.colorTag.replace({rgbValue: color}, infoTip);
- return true;
- },
-
- populateImageInfoTip: function(infoTip, url, repeat)
- {
- if (!repeat)
- repeat = "no-repeat";
-
- this.tags.imgTag.replace({urlValue: url, repeat: repeat}, infoTip);
-
- return true;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // extends Module
-
- disable: function()
- {
- // XXXjoe For each browser, call uninitializeBrowser
- },
-
- showPanel: function(browser, panel)
- {
- if (panel)
- {
- var infoTip = panel.panelBrowser.infoTip;
- if (!infoTip)
- infoTip = this.initializeBrowser(panel.panelBrowser);
- this.hideInfoTip(infoTip);
- }
-
- },
-
- showSidePanel: function(browser, panel)
- {
- this.showPanel(browser, panel);
- }
-});
-
-// ************************************************************************************************
-
-Firebug.registerModule(Firebug.InfoTip);
-
-// ************************************************************************************************
-
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-var CssParser = null;
-
-// ************************************************************************************************
-
-// Simple CSS stylesheet parser from:
-// https://github.com/sergeche/webkit-css
-
-/**
- * Simple CSS stylesheet parser that remembers rule's lines in file
- * @author Sergey Chikuyonok (serge.che@gmail.com)
- * @link http://chikuyonok.ru
- */
-CssParser = (function(){
- /**
- * Returns rule object
- * @param {Number} start Character index where CSS rule definition starts
- * @param {Number} body_start Character index where CSS rule's body starts
- * @param {Number} end Character index where CSS rule definition ends
- */
- function rule(start, body_start, end) {
- return {
- start: start || 0,
- body_start: body_start || 0,
- end: end || 0,
- line: -1,
- selector: null,
- parent: null,
-
- /** @type {rule[]} */
- children: [],
-
- addChild: function(start, body_start, end) {
- var r = rule(start, body_start, end);
- r.parent = this;
- this.children.push(r);
- return r;
- },
- /**
- * Returns last child element
- * @return {rule}
- */
- lastChild: function() {
- return this.children[this.children.length - 1];
- }
- };
- }
-
- /**
- * Replaces all occurances of substring defined by regexp
- * @param {String} str
- * @return {RegExp} re
- * @return {String}
- */
- function removeAll(str, re) {
- var m;
- while (m = str.match(re)) {
- str = str.substring(m[0].length);
- }
-
- return str;
- }
-
- /**
- * Trims whitespace from the beginning and the end of string
- * @param {String} str
- * @return {String}
- */
- function trim(str) {
- return str.replace(/^\s+|\s+$/g, '');
- }
-
- /**
- * Normalizes CSS rules selector
- * @param {String} selector
- */
- function normalizeSelector(selector) {
- // remove newlines
- selector = selector.replace(/[\n\r]/g, ' ');
-
- selector = trim(selector);
-
- // remove spaces after commas
- selector = selector.replace(/\s*,\s*/g, ',');
-
- return selector;
- }
-
- /**
- * Preprocesses parsed rules: adjusts char indexes, skipping whitespace and
- * newlines, saves rule selector, removes comments, etc.
- * @param {String} text CSS stylesheet
- * @param {rule} rule_node CSS rule node
- * @return {rule[]}
- */
- function preprocessRules(text, rule_node) {
- for (var i = 0, il = rule_node.children.length; i < il; i++) {
- var r = rule_node.children[i],
- rule_start = text.substring(r.start, r.body_start),
- cur_len = rule_start.length;
-
- // remove newlines for better regexp matching
- rule_start = rule_start.replace(/[\n\r]/g, ' ');
-
- // remove @import rules
-// rule_start = removeAll(rule_start, /^\s*@import\s*url\((['"])?.+?\1?\)\;?/g);
-
- // remove comments
- rule_start = removeAll(rule_start, /^\s*\/\*.*?\*\/[\s\t]*/);
-
- // remove whitespace
- rule_start = rule_start.replace(/^[\s\t]+/, '');
-
- r.start += (cur_len - rule_start.length);
- r.selector = normalizeSelector(rule_start);
- }
-
- return rule_node;
- }
-
- /**
- * Saves all lise starting indexes for faster search
- * @param {String} text CSS stylesheet
- * @return {Number[]}
- */
- function saveLineIndexes(text) {
- var result = [0],
- i = 0,
- il = text.length,
- ch, ch2;
-
- while (i < il) {
- ch = text.charAt(i);
-
- if (ch == '\n' || ch == '\r') {
- if (ch == '\r' && i < il - 1 && text.charAt(i + 1) == '\n') {
- // windows line ending: CRLF. Skip next character
- i++;
- }
-
- result.push(i + 1);
- }
-
- i++;
- }
-
- return result;
- }
-
- /**
- * Saves line number for parsed rules
- * @param {String} text CSS stylesheet
- * @param {rule} rule_node Rule node
- * @return {rule[]}
- */
- function saveLineNumbers(text, rule_node, line_indexes, startLine) {
- preprocessRules(text, rule_node);
-
- startLine = startLine || 0;
-
- // remember lines start indexes, preserving line ending characters
- if (!line_indexes)
- var line_indexes = saveLineIndexes(text);
-
- // now find each rule's line
- for (var i = 0, il = rule_node.children.length; i < il; i++) {
- var r = rule_node.children[i];
- r.line = line_indexes.length + startLine;
- for (var j = 0, jl = line_indexes.length - 1; j < jl; j++) {
- var line_ix = line_indexes[j];
- if (r.start >= line_indexes[j] && r.start < line_indexes[j + 1]) {
- r.line = j + 1 + startLine;
- break;
- }
- }
-
- saveLineNumbers(text, r, line_indexes);
- }
-
- return rule_node;
- }
-
- return {
- /**
- * Parses text as CSS stylesheet, remembring each rule position inside
- * text
- * @param {String} text CSS stylesheet to parse
- */
- read: function(text, startLine) {
- var rule_start = [],
- rule_body_start = [],
- rules = [],
- in_comment = 0,
- root = rule(),
- cur_parent = root,
- last_rule = null,
- stack = [],
- ch, ch2;
-
- stack.last = function() {
- return this[this.length - 1];
- };
-
- function hasStr(pos, substr) {
- return text.substr(pos, substr.length) == substr;
- }
-
- for (var i = 0, il = text.length; i < il; i++) {
- ch = text.charAt(i);
- ch2 = i < il - 1 ? text.charAt(i + 1) : '';
-
- if (!rule_start.length)
- rule_start.push(i);
-
- switch (ch) {
- case '@':
- if (!in_comment) {
- if (hasStr(i, '@import')) {
- var m = text.substr(i).match(/^@import\s*url\((['"])?.+?\1?\)\;?/);
- if (m) {
- cur_parent.addChild(i, i + 7, i + m[0].length);
- i += m[0].length;
- rule_start.pop();
- }
- break;
- }
- }
- case '/':
- // xxxpedro allowing comment inside comment
- if (!in_comment && ch2 == '*') { // comment start
- in_comment++;
- }
- break;
-
- case '*':
- if (ch2 == '/') { // comment end
- in_comment--;
- }
- break;
-
- case '{':
- if (!in_comment) {
- rule_body_start.push(i);
-
- cur_parent = cur_parent.addChild(rule_start.pop());
- stack.push(cur_parent);
- }
- break;
-
- case '}':
- // found the end of the rule
- if (!in_comment) {
- /** @type {rule} */
- var last_rule = stack.pop();
- rule_start.pop();
- last_rule.body_start = rule_body_start.pop();
- last_rule.end = i;
- cur_parent = last_rule.parent || root;
- }
- break;
- }
-
- }
-
- return saveLineNumbers(text, root, null, startLine);
- },
-
- normalizeSelector: normalizeSelector,
-
- /**
- * Find matched rule by selector.
- * @param {rule} rule_node Parsed rule node
- * @param {String} selector CSS selector
- * @param {String} source CSS stylesheet source code
- *
- * @return {rule[]|null} Array of matched rules, sorted by priority (most
- * recent on top)
- */
- findBySelector: function(rule_node, selector, source) {
- var selector = normalizeSelector(selector),
- result = [];
-
- if (rule_node) {
- for (var i = 0, il = rule_node.children.length; i < il; i++) {
- /** @type {rule} */
- var r = rule_node.children[i];
- if (r.selector == selector) {
- result.push(r);
- }
- }
- }
-
- if (result.length) {
- return result;
- } else {
- return null;
- }
- }
- };
-})();
-
-
-// ************************************************************************************************
-
-FBL.CssParser = CssParser;
-
-// ************************************************************************************************
-}});
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-
-// ************************************************************************************************
-// StyleSheet Parser
-
-var CssAnalyzer = {};
-
-// ************************************************************************************************
-// Locals
-
-var CSSRuleMap = {};
-var ElementCSSRulesMap = {};
-
-var internalStyleSheetIndex = -1;
-
-var reSelectorTag = /(^|\s)(?:\w+)/g;
-var reSelectorClass = /\.[\w\d_-]+/g;
-var reSelectorId = /#[\w\d_-]+/g;
-
-var globalCSSRuleIndex;
-
-var processAllStyleSheetsTimeout = null;
-
-var externalStyleSheetURLs = [];
-
-var ElementCache = Firebug.Lite.Cache.Element;
-var StyleSheetCache = Firebug.Lite.Cache.StyleSheet;
-
-//************************************************************************************************
-// CSS Analyzer templates
-
-CssAnalyzer.externalStyleSheetWarning = domplate(Firebug.Rep,
-{
- tag:
- DIV({"class": "warning focusRow", style: "font-weight:normal;", role: 'listitem'},
- SPAN("$object|STR"),
- A({"href": "$href", target:"_blank"}, "$link|STR")
- )
-});
-
-// ************************************************************************************************
-// CSS Analyzer methods
-
-CssAnalyzer.processAllStyleSheets = function(doc, styleSheetIterator)
-{
- try
- {
- processAllStyleSheets(doc, styleSheetIterator);
- }
- catch(e)
- {
- // TODO: FBTrace condition
- FBTrace.sysout("CssAnalyzer.processAllStyleSheets fails: ", e);
- }
-};
-
-/**
- *
- * @param element
- * @returns {String[]} Array of IDs of CSS Rules
- */
-CssAnalyzer.getElementCSSRules = function(element)
-{
- try
- {
- return getElementCSSRules(element);
- }
- catch(e)
- {
- // TODO: FBTrace condition
- FBTrace.sysout("CssAnalyzer.getElementCSSRules fails: ", e);
- }
-};
-
-CssAnalyzer.getRuleData = function(ruleId)
-{
- return CSSRuleMap[ruleId];
-};
-
-// TODO: do we need this?
-CssAnalyzer.getRuleLine = function()
-{
-};
-
-CssAnalyzer.hasExternalStyleSheet = function()
-{
- return externalStyleSheetURLs.length > 0;
-};
-
-CssAnalyzer.parseStyleSheet = function(href)
-{
- var sourceData = extractSourceData(href);
- var parsedObj = CssParser.read(sourceData.source, sourceData.startLine);
- var parsedRules = parsedObj.children;
-
- // See: Issue 4776: [Firebug lite] CSS Media Types
- //
- // Ignore all special selectors like @media and @page
- for(var i=0; i < parsedRules.length; )
- {
- if (parsedRules[i].selector.indexOf("@") != -1)
- {
- parsedRules.splice(i, 1);
- }
- else
- i++;
- }
-
- return parsedRules;
-};
-
-//************************************************************************************************
-// Internals
-//************************************************************************************************
-
-// ************************************************************************************************
-// StyleSheet processing
-
-var processAllStyleSheets = function(doc, styleSheetIterator)
-{
- styleSheetIterator = styleSheetIterator || processStyleSheet;
-
- globalCSSRuleIndex = -1;
-
- var styleSheets = doc.styleSheets;
- var importedStyleSheets = [];
-
- if (FBTrace.DBG_CSS)
- var start = new Date().getTime();
-
- for(var i=0, length=styleSheets.length; i<length; i++)
- {
- try
- {
- var styleSheet = styleSheets[i];
-
- if ("firebugIgnore" in styleSheet) continue;
-
- // we must read the length to make sure we have permission to read
- // the stylesheet's content. If an error occurs here, we cannot
- // read the stylesheet due to access restriction policy
- var rules = isIE ? styleSheet.rules : styleSheet.cssRules;
- rules.length;
- }
- catch(e)
- {
- externalStyleSheetURLs.push(styleSheet.href);
- styleSheet.restricted = true;
- var ssid = StyleSheetCache(styleSheet);
-
- /// TODO: xxxpedro external css
- //loadExternalStylesheet(doc, styleSheetIterator, styleSheet);
- }
-
- // process internal and external styleSheets
- styleSheetIterator(doc, styleSheet);
-
- var importedStyleSheet, importedRules;
-
- // process imported styleSheets in IE
- if (isIE)
- {
- var imports = styleSheet.imports;
-
- for(var j=0, importsLength=imports.length; j<importsLength; j++)
- {
- try
- {
- importedStyleSheet = imports[j];
- // we must read the length to make sure we have permission
- // to read the imported stylesheet's content.
- importedRules = importedStyleSheet.rules;
- importedRules.length;
- }
- catch(e)
- {
- externalStyleSheetURLs.push(styleSheet.href);
- importedStyleSheet.restricted = true;
- var ssid = StyleSheetCache(importedStyleSheet);
- }
-
- styleSheetIterator(doc, importedStyleSheet);
- }
- }
- // process imported styleSheets in other browsers
- else if (rules)
- {
- for(var j=0, rulesLength=rules.length; j<rulesLength; j++)
- {
- try
- {
- var rule = rules[j];
-
- importedStyleSheet = rule.styleSheet;
-
- if (importedStyleSheet)
- {
- // we must read the length to make sure we have permission
- // to read the imported stylesheet's content.
- importedRules = importedStyleSheet.cssRules;
- importedRules.length;
- }
- else
- break;
- }
- catch(e)
- {
- externalStyleSheetURLs.push(styleSheet.href);
- importedStyleSheet.restricted = true;
- var ssid = StyleSheetCache(importedStyleSheet);
- }
-
- styleSheetIterator(doc, importedStyleSheet);
- }
- }
- };
-
- if (FBTrace.DBG_CSS)
- {
- FBTrace.sysout("FBL.processAllStyleSheets", "all stylesheet rules processed in " + (new Date().getTime() - start) + "ms");
- }
-};
-
-// ************************************************************************************************
-
-var processStyleSheet = function(doc, styleSheet)
-{
- if (styleSheet.restricted)
- return;
-
- var rules = isIE ? styleSheet.rules : styleSheet.cssRules;
-
- var ssid = StyleSheetCache(styleSheet);
-
- var href = styleSheet.href;
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // CSS Parser
- var shouldParseCSS = typeof CssParser != "undefined" && !Firebug.disableResourceFetching;
- if (shouldParseCSS)
- {
- try
- {
- var parsedRules = CssAnalyzer.parseStyleSheet(href);
- }
- catch(e)
- {
- if (FBTrace.DBG_ERRORS) FBTrace.sysout("processStyleSheet FAILS", e.message || e);
- shouldParseCSS = false;
- }
- finally
- {
- var parsedRulesIndex = 0;
-
- var dontSupportGroupedRules = isIE && browserVersion < 9;
- var group = [];
- var groupItem;
- }
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- for (var i=0, length=rules.length; i<length; i++)
- {
- // TODO: xxxpedro is there a better way to cache CSS Rules? The problem is that
- // we cannot add expando properties in the rule object in IE
- var rid = ssid + ":" + i;
- var rule = rules[i];
- var selector = rule.selectorText || "";
- var lineNo = null;
-
- // See: Issue 4776: [Firebug lite] CSS Media Types
- //
- // Ignore all special selectors like @media and @page
- if (!selector || selector.indexOf("@") != -1)
- continue;
-
- if (isIE)
- selector = selector.replace(reSelectorTag, function(s){return s.toLowerCase();});
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // CSS Parser
- if (shouldParseCSS)
- {
- var parsedRule = parsedRules[parsedRulesIndex];
- var parsedSelector = parsedRule.selector;
-
- if (dontSupportGroupedRules && parsedSelector.indexOf(",") != -1 && group.length == 0)
- group = parsedSelector.split(",");
-
- if (dontSupportGroupedRules && group.length > 0)
- {
- groupItem = group.shift();
-
- if (CssParser.normalizeSelector(selector) == groupItem)
- lineNo = parsedRule.line;
-
- if (group.length == 0)
- parsedRulesIndex++;
- }
- else if (CssParser.normalizeSelector(selector) == parsedRule.selector)
- {
- lineNo = parsedRule.line;
- parsedRulesIndex++;
- }
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- CSSRuleMap[rid] =
- {
- styleSheetId: ssid,
- styleSheetIndex: i,
- order: ++globalCSSRuleIndex,
- specificity:
- // See: Issue 4777: [Firebug lite] Specificity of CSS Rules
- //
- // if it is a normal selector then calculate the specificity
- selector && selector.indexOf(",") == -1 ?
- getCSSRuleSpecificity(selector) :
- // See: Issue 3262: [Firebug lite] Specificity of grouped CSS Rules
- //
- // if it is a grouped selector, do not calculate the specificity
- // because the correct value will depend of the matched element.
- // The proper specificity value for grouped selectors are calculated
- // via getElementCSSRules(element)
- 0,
-
- rule: rule,
- lineNo: lineNo,
- selector: selector,
- cssText: rule.style ? rule.style.cssText : rule.cssText ? rule.cssText : ""
- };
-
- // TODO: what happens with elements added after this? Need to create a test case.
- // Maybe we should place this at getElementCSSRules() but it will make the function
- // a lot more expensive.
- //
- // Maybe add a "refresh" button?
- var elements = Firebug.Selector(selector, doc);
-
- for (var j=0, elementsLength=elements.length; j<elementsLength; j++)
- {
- var element = elements[j];
- var eid = ElementCache(element);
-
- if (!ElementCSSRulesMap[eid])
- ElementCSSRulesMap[eid] = [];
-
- ElementCSSRulesMap[eid].push(rid);
- }
-
- //console.log(selector, elements);
- }
-};
-
-// ************************************************************************************************
-// External StyleSheet Loader
-
-var loadExternalStylesheet = function(doc, styleSheetIterator, styleSheet)
-{
- var url = styleSheet.href;
- styleSheet.firebugIgnore = true;
-
- var source = Firebug.Lite.Proxy.load(url);
-
- // TODO: check for null and error responses
-
- // remove comments
- //var reMultiComment = /(\/\*([^\*]|\*(?!\/))*\*\/)/g;
- //source = source.replace(reMultiComment, "");
-
- // convert relative addresses to absolute ones
- source = source.replace(/url\(([^\)]+)\)/g, function(a,name){
-
- var hasDomain = /\w+:\/\/./.test(name);
-
- if (!hasDomain)
- {
- name = name.replace(/^(["'])(.+)\1$/, "$2");
- var first = name.charAt(0);
-
- // relative path, based on root
- if (first == "/")
- {
- // TODO: xxxpedro move to lib or Firebug.Lite.something
- // getURLRoot
- var m = /^([^:]+:\/{1,3}[^\/]+)/.exec(url);
-
- return m ?
- "url(" + m[1] + name + ")" :
- "url(" + name + ")";
- }
- // relative path, based on current location
- else
- {
- // TODO: xxxpedro move to lib or Firebug.Lite.something
- // getURLPath
- var path = url.replace(/[^\/]+\.[\w\d]+(\?.+|#.+)?$/g, "");
-
- path = path + name;
-
- var reBack = /[^\/]+\/\.\.\//;
- while(reBack.test(path))
- {
- path = path.replace(reBack, "");
- }
-
- //console.log("url(" + path + ")");
-
- return "url(" + path + ")";
- }
- }
-
- // if it is an absolute path, there is nothing to do
- return a;
- });
-
- var oldStyle = styleSheet.ownerNode;
-
- if (!oldStyle) return;
-
- if (!oldStyle.parentNode) return;
-
- var style = createGlobalElement("style");
- style.setAttribute("charset","utf-8");
- style.setAttribute("type", "text/css");
- style.innerHTML = source;
-
- //debugger;
- oldStyle.parentNode.insertBefore(style, oldStyle.nextSibling);
- oldStyle.parentNode.removeChild(oldStyle);
-
- doc.styleSheets[doc.styleSheets.length-1].externalURL = url;
-
- console.log(url, "call " + externalStyleSheetURLs.length, source);
-
- externalStyleSheetURLs.pop();
-
- if (processAllStyleSheetsTimeout)
- {
- clearTimeout(processAllStyleSheetsTimeout);
- }
-
- processAllStyleSheetsTimeout = setTimeout(function(){
- console.log("processing");
- FBL.processAllStyleSheets(doc, styleSheetIterator);
- processAllStyleSheetsTimeout = null;
- },200);
-
-};
-
-//************************************************************************************************
-// getElementCSSRules
-
-var getElementCSSRules = function(element)
-{
- var eid = ElementCache(element);
- var rules = ElementCSSRulesMap[eid];
-
- if (!rules) return;
-
- var arr = [element];
- var Selector = Firebug.Selector;
- var ruleId, rule;
-
- // for the case of grouped selectors, we need to calculate the highest
- // specificity within the selectors of the group that matches the element,
- // so we can sort the rules properly without over estimating the specificity
- // of grouped selectors
- for (var i = 0, length = rules.length; i < length; i++)
- {
- ruleId = rules[i];
- rule = CSSRuleMap[ruleId];
-
- // check if it is a grouped selector
- if (rule.selector.indexOf(",") != -1)
- {
- var selectors = rule.selector.split(",");
- var maxSpecificity = -1;
- var sel, spec, mostSpecificSelector;
-
- // loop over all selectors in the group
- for (var j, len = selectors.length; j < len; j++)
- {
- sel = selectors[j];
-
- // find if the selector matches the element
- if (Selector.matches(sel, arr).length == 1)
- {
- spec = getCSSRuleSpecificity(sel);
-
- // find the most specific selector that macthes the element
- if (spec > maxSpecificity)
- {
- maxSpecificity = spec;
- mostSpecificSelector = sel;
- }
- }
- }
-
- rule.specificity = maxSpecificity;
- }
- }
-
- rules.sort(sortElementRules);
- //rules.sort(solveRulesTied);
-
- return rules;
-};
-
-// ************************************************************************************************
-// Rule Specificity
-
-var sortElementRules = function(a, b)
-{
- var ruleA = CSSRuleMap[a];
- var ruleB = CSSRuleMap[b];
-
- var specificityA = ruleA.specificity;
- var specificityB = ruleB.specificity;
-
- if (specificityA > specificityB)
- return 1;
-
- else if (specificityA < specificityB)
- return -1;
-
- else
- return ruleA.order > ruleB.order ? 1 : -1;
-};
-
-var solveRulesTied = function(a, b)
-{
- var ruleA = CSSRuleMap[a];
- var ruleB = CSSRuleMap[b];
-
- if (ruleA.specificity == ruleB.specificity)
- return ruleA.order > ruleB.order ? 1 : -1;
-
- return null;
-};
-
-var getCSSRuleSpecificity = function(selector)
-{
- var match = selector.match(reSelectorTag);
- var tagCount = match ? match.length : 0;
-
- match = selector.match(reSelectorClass);
- var classCount = match ? match.length : 0;
-
- match = selector.match(reSelectorId);
- var idCount = match ? match.length : 0;
-
- return tagCount + 10*classCount + 100*idCount;
-};
-
-// ************************************************************************************************
-// StyleSheet data
-
-var extractSourceData = function(href)
-{
- var sourceData =
- {
- source: null,
- startLine: 0
- };
-
- if (href)
- {
- sourceData.source = Firebug.Lite.Proxy.load(href);
- }
- else
- {
- // TODO: create extractInternalSourceData(index)
- // TODO: pre process the position of the inline styles so this will happen only once
- // in case of having multiple inline styles
- var index = 0;
- var ssIndex = ++internalStyleSheetIndex;
- var reStyleTag = /\<\s*style.*\>/gi;
- var reEndStyleTag = /\<\/\s*style.*\>/gi;
-
- var source = Firebug.Lite.Proxy.load(Env.browser.location.href);
- source = source.replace(/\n\r|\r\n/g, "\n"); // normalize line breaks
-
- var startLine = 0;
-
- do
- {
- var matchStyleTag = source.match(reStyleTag);
- var i0 = source.indexOf(matchStyleTag[0]) + matchStyleTag[0].length;
-
- for (var i=0; i < i0; i++)
- {
- if (source.charAt(i) == "\n")
- startLine++;
- }
-
- source = source.substr(i0);
-
- index++;
- }
- while (index <= ssIndex);
-
- var matchEndStyleTag = source.match(reEndStyleTag);
- var i1 = source.indexOf(matchEndStyleTag[0]);
-
- var extractedSource = source.substr(0, i1);
-
- sourceData.source = extractedSource;
- sourceData.startLine = startLine;
- }
-
- return sourceData;
-};
-
-// ************************************************************************************************
-// Registration
-
-FBL.CssAnalyzer = CssAnalyzer;
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-// move to FBL
-(function() {
-
-// ************************************************************************************************
-// XPath
-
-/**
- * Gets an XPath for an element which describes its hierarchical location.
- */
-this.getElementXPath = function(element)
-{
- try
- {
- if (element && element.id)
- return '//*[@id="' + element.id + '"]';
- else
- return this.getElementTreeXPath(element);
- }
- catch(E)
- {
- // xxxpedro: trying to detect the mysterious error:
- // Security error" code: "1000
- //debugger;
- }
-};
-
-this.getElementTreeXPath = function(element)
-{
- var paths = [];
-
- for (; element && element.nodeType == 1; element = element.parentNode)
- {
- var index = 0;
- var nodeName = element.nodeName;
-
- for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling)
- {
- if (sibling.nodeType != 1) continue;
-
- if (sibling.nodeName == nodeName)
- ++index;
- }
-
- var tagName = element.nodeName.toLowerCase();
- var pathIndex = (index ? "[" + (index+1) + "]" : "");
- paths.splice(0, 0, tagName + pathIndex);
- }
-
- return paths.length ? "/" + paths.join("/") : null;
-};
-
-this.getElementsByXPath = function(doc, xpath)
-{
- var nodes = [];
-
- try {
- var result = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null);
- for (var item = result.iterateNext(); item; item = result.iterateNext())
- nodes.push(item);
- }
- catch (exc)
- {
- // Invalid xpath expressions make their way here sometimes. If that happens,
- // we still want to return an empty set without an exception.
- }
-
- return nodes;
-};
-
-this.getRuleMatchingElements = function(rule, doc)
-{
- var css = rule.selectorText;
- var xpath = this.cssToXPath(css);
- return this.getElementsByXPath(doc, xpath);
-};
-
-
-}).call(FBL);
-
-
-
-
-FBL.ns(function() { with (FBL) {
-
-// ************************************************************************************************
-// ************************************************************************************************
-// ************************************************************************************************
-// ************************************************************************************************
-// ************************************************************************************************
-
-var toCamelCase = function toCamelCase(s)
-{
- return s.replace(reSelectorCase, toCamelCaseReplaceFn);
-};
-
-var toSelectorCase = function toSelectorCase(s)
-{
- return s.replace(reCamelCase, "-$1").toLowerCase();
-
-};
-
-var reCamelCase = /([A-Z])/g;
-var reSelectorCase = /\-(.)/g;
-var toCamelCaseReplaceFn = function toCamelCaseReplaceFn(m,g)
-{
- return g.toUpperCase();
-};
-
-// ************************************************************************************************
-
-var ElementCache = Firebug.Lite.Cache.Element;
-var StyleSheetCache = Firebug.Lite.Cache.StyleSheet;
-
-// ************************************************************************************************
-// ************************************************************************************************
-// ************************************************************************************************
-// ************************************************************************************************
-// ************************************************************************************************
-// ************************************************************************************************
-
-
-// ************************************************************************************************
-// Constants
-
-//const Cc = Components.classes;
-//const Ci = Components.interfaces;
-//const nsIDOMCSSStyleRule = Ci.nsIDOMCSSStyleRule;
-//const nsIInterfaceRequestor = Ci.nsIInterfaceRequestor;
-//const nsISelectionDisplay = Ci.nsISelectionDisplay;
-//const nsISelectionController = Ci.nsISelectionController;
-
-// See: http://mxr.mozilla.org/mozilla1.9.2/source/content/events/public/nsIEventStateManager.h#153
-//const STATE_ACTIVE = 0x01;
-//const STATE_FOCUS = 0x02;
-//const STATE_HOVER = 0x04;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-Firebug.SourceBoxPanel = Firebug.Panel;
-
-var reSelectorTag = /(^|\s)(?:\w+)/g;
-
-var domUtils = null;
-
-var textContent = isIE ? "innerText" : "textContent";
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var CSSDomplateBase = {
- isEditable: function(rule)
- {
- return !rule.isSystemSheet;
- },
- isSelectorEditable: function(rule)
- {
- return rule.isSelectorEditable && this.isEditable(rule);
- }
-};
-
-var CSSPropTag = domplate(CSSDomplateBase, {
- tag: DIV({"class": "cssProp focusRow", $disabledStyle: "$prop.disabled",
- $editGroup: "$rule|isEditable",
- $cssOverridden: "$prop.overridden", role : "option"},
- A({"class": "cssPropDisable"}, "&nbsp;&nbsp;"),
- SPAN({"class": "cssPropName", $editable: "$rule|isEditable"}, "$prop.name"),
- SPAN({"class": "cssColon"}, ":"),
- SPAN({"class": "cssPropValue", $editable: "$rule|isEditable"}, "$prop.value$prop.important"),
- SPAN({"class": "cssSemi"}, ";")
- )
-});
-
-var CSSRuleTag =
- TAG("$rule.tag", {rule: "$rule"});
-
-var CSSImportRuleTag = domplate({
- tag: DIV({"class": "cssRule insertInto focusRow importRule", _repObject: "$rule.rule"},
- "@import &quot;",
- A({"class": "objectLink", _repObject: "$rule.rule.styleSheet"}, "$rule.rule.href"),
- "&quot;;"
- )
-});
-
-var CSSStyleRuleTag = domplate(CSSDomplateBase, {
- tag: DIV({"class": "cssRule insertInto",
- $cssEditableRule: "$rule|isEditable",
- $editGroup: "$rule|isSelectorEditable",
- _repObject: "$rule.rule",
- "ruleId": "$rule.id", role : 'presentation'},
- DIV({"class": "cssHead focusRow", role : 'listitem'},
- SPAN({"class": "cssSelector", $editable: "$rule|isSelectorEditable"}, "$rule.selector"), " {"
- ),
- DIV({role : 'group'},
- DIV({"class": "cssPropertyListBox", role : 'listbox'},
- FOR("prop", "$rule.props",
- TAG(CSSPropTag.tag, {rule: "$rule", prop: "$prop"})
- )
- )
- ),
- DIV({"class": "editable insertBefore", role:"presentation"}, "}")
- )
-});
-
-var reSplitCSS = /(url\("?[^"\)]+?"?\))|(rgb\(.*?\))|(#[\dA-Fa-f]+)|(-?\d+(\.\d+)?(%|[a-z]{1,2})?)|([^,\s]+)|"(.*?)"/;
-
-var reURL = /url\("?([^"\)]+)?"?\)/;
-
-var reRepeat = /no-repeat|repeat-x|repeat-y|repeat/;
-
-//const sothinkInstalled = !!$("swfcatcherKey_sidebar");
-var sothinkInstalled = false;
-var styleGroups =
-{
- text: [
- "font-family",
- "font-size",
- "font-weight",
- "font-style",
- "color",
- "text-transform",
- "text-decoration",
- "letter-spacing",
- "word-spacing",
- "line-height",
- "text-align",
- "vertical-align",
- "direction",
- "column-count",
- "column-gap",
- "column-width"
- ],
-
- background: [
- "background-color",
- "background-image",
- "background-repeat",
- "background-position",
- "background-attachment",
- "opacity"
- ],
-
- box: [
- "width",
- "height",
- "top",
- "right",
- "bottom",
- "left",
- "margin-top",
- "margin-right",
- "margin-bottom",
- "margin-left",
- "padding-top",
- "padding-right",
- "padding-bottom",
- "padding-left",
- "border-top-width",
- "border-right-width",
- "border-bottom-width",
- "border-left-width",
- "border-top-color",
- "border-right-color",
- "border-bottom-color",
- "border-left-color",
- "border-top-style",
- "border-right-style",
- "border-bottom-style",
- "border-left-style",
- "-moz-border-top-radius",
- "-moz-border-right-radius",
- "-moz-border-bottom-radius",
- "-moz-border-left-radius",
- "outline-top-width",
- "outline-right-width",
- "outline-bottom-width",
- "outline-left-width",
- "outline-top-color",
- "outline-right-color",
- "outline-bottom-color",
- "outline-left-color",
- "outline-top-style",
- "outline-right-style",
- "outline-bottom-style",
- "outline-left-style"
- ],
-
- layout: [
- "position",
- "display",
- "visibility",
- "z-index",
- "overflow-x", // http://www.w3.org/TR/2002/WD-css3-box-20021024/#overflow
- "overflow-y",
- "overflow-clip",
- "white-space",
- "clip",
- "float",
- "clear",
- "-moz-box-sizing"
- ],
-
- other: [
- "cursor",
- "list-style-image",
- "list-style-position",
- "list-style-type",
- "marker-offset",
- "user-focus",
- "user-select",
- "user-modify",
- "user-input"
- ]
-};
-
-var styleGroupTitles =
-{
- text: "Text",
- background: "Background",
- box: "Box Model",
- layout: "Layout",
- other: "Other"
-};
-
-Firebug.CSSModule = extend(Firebug.Module,
-{
- freeEdit: function(styleSheet, value)
- {
- if (!styleSheet.editStyleSheet)
- {
- var ownerNode = getStyleSheetOwnerNode(styleSheet);
- styleSheet.disabled = true;
-
- var url = CCSV("@mozilla.org/network/standard-url;1", Components.interfaces.nsIURL);
- url.spec = styleSheet.href;
-
- var editStyleSheet = ownerNode.ownerDocument.createElementNS(
- "http://www.w3.org/1999/xhtml",
- "style");
- unwrapObject(editStyleSheet).firebugIgnore = true;
- editStyleSheet.setAttribute("type", "text/css");
- editStyleSheet.setAttributeNS(
- "http://www.w3.org/XML/1998/namespace",
- "base",
- url.directory);
- if (ownerNode.hasAttribute("media"))
- {
- editStyleSheet.setAttribute("media", ownerNode.getAttribute("media"));
- }
-
- // Insert the edited stylesheet directly after the old one to ensure the styles
- // cascade properly.
- ownerNode.parentNode.insertBefore(editStyleSheet, ownerNode.nextSibling);
-
- styleSheet.editStyleSheet = editStyleSheet;
- }
-
- styleSheet.editStyleSheet.innerHTML = value;
- if (FBTrace.DBG_CSS)
- FBTrace.sysout("css.saveEdit styleSheet.href:"+styleSheet.href+" got innerHTML:"+value+"\n");
-
- dispatch(this.fbListeners, "onCSSFreeEdit", [styleSheet, value]);
- },
-
- insertRule: function(styleSheet, cssText, ruleIndex)
- {
- if (FBTrace.DBG_CSS) FBTrace.sysout("Insert: " + ruleIndex + " " + cssText);
- var insertIndex = styleSheet.insertRule(cssText, ruleIndex);
-
- dispatch(this.fbListeners, "onCSSInsertRule", [styleSheet, cssText, ruleIndex]);
-
- return insertIndex;
- },
-
- deleteRule: function(styleSheet, ruleIndex)
- {
- if (FBTrace.DBG_CSS) FBTrace.sysout("deleteRule: " + ruleIndex + " " + styleSheet.cssRules.length, styleSheet.cssRules);
- dispatch(this.fbListeners, "onCSSDeleteRule", [styleSheet, ruleIndex]);
-
- styleSheet.deleteRule(ruleIndex);
- },
-
- setProperty: function(rule, propName, propValue, propPriority)
- {
- var style = rule.style || rule;
-
- // Record the original CSS text for the inline case so we can reconstruct at a later
- // point for diffing purposes
- var baseText = style.cssText;
-
- // good browsers
- if (style.getPropertyValue)
- {
- var prevValue = style.getPropertyValue(propName);
- var prevPriority = style.getPropertyPriority(propName);
-
- // XXXjoe Gecko bug workaround: Just changing priority doesn't have any effect
- // unless we remove the property first
- style.removeProperty(propName);
-
- style.setProperty(propName, propValue, propPriority);
- }
- // sad browsers
- else
- {
- // TODO: xxxpedro parse CSS rule to find property priority in IE?
- //console.log(propName, propValue);
- style[toCamelCase(propName)] = propValue;
- }
-
- if (propName) {
- dispatch(this.fbListeners, "onCSSSetProperty", [style, propName, propValue, propPriority, prevValue, prevPriority, rule, baseText]);
- }
- },
-
- removeProperty: function(rule, propName, parent)
- {
- var style = rule.style || rule;
-
- // Record the original CSS text for the inline case so we can reconstruct at a later
- // point for diffing purposes
- var baseText = style.cssText;
-
- if (style.getPropertyValue)
- {
-
- var prevValue = style.getPropertyValue(propName);
- var prevPriority = style.getPropertyPriority(propName);
-
- style.removeProperty(propName);
- }
- else
- {
- style[toCamelCase(propName)] = "";
- }
-
- if (propName) {
- dispatch(this.fbListeners, "onCSSRemoveProperty", [style, propName, prevValue, prevPriority, rule, baseText]);
- }
- }/*,
-
- cleanupSheets: function(doc, context)
- {
- // Due to the manner in which the layout engine handles multiple
- // references to the same sheet we need to kick it a little bit.
- // The injecting a simple stylesheet then removing it will force
- // Firefox to regenerate it's CSS hierarchy.
- //
- // WARN: This behavior was determined anecdotally.
- // See http://code.google.com/p/fbug/issues/detail?id=2440
- var style = doc.createElementNS("http://www.w3.org/1999/xhtml", "style");
- style.setAttribute("charset","utf-8");
- unwrapObject(style).firebugIgnore = true;
- style.setAttribute("type", "text/css");
- style.innerHTML = "#fbIgnoreStyleDO_NOT_USE {}";
- addStyleSheet(doc, style);
- style.parentNode.removeChild(style);
-
- // https://bugzilla.mozilla.org/show_bug.cgi?id=500365
- // This voodoo touches each style sheet to force some Firefox internal change to allow edits.
- var styleSheets = getAllStyleSheets(context);
- for(var i = 0; i < styleSheets.length; i++)
- {
- try
- {
- var rules = styleSheets[i].cssRules;
- if (rules.length > 0)
- var touch = rules[0];
- if (FBTrace.DBG_CSS && touch)
- FBTrace.sysout("css.show() touch "+typeof(touch)+" in "+(styleSheets[i].href?styleSheets[i].href:context.getName()));
- }
- catch(e)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("css.show: sheet.cssRules FAILS for "+(styleSheets[i]?styleSheets[i].href:"null sheet")+e, e);
- }
- }
- },
- cleanupSheetHandler: function(event, context)
- {
- var target = event.target || event.srcElement,
- tagName = (target.tagName || "").toLowerCase();
- if (tagName == "link")
- {
- this.cleanupSheets(target.ownerDocument, context);
- }
- },
- watchWindow: function(context, win)
- {
- var cleanupSheets = bind(this.cleanupSheets, this),
- cleanupSheetHandler = bind(this.cleanupSheetHandler, this, context),
- doc = win.document;
-
- //doc.addEventListener("DOMAttrModified", cleanupSheetHandler, false);
- //doc.addEventListener("DOMNodeInserted", cleanupSheetHandler, false);
- },
- loadedContext: function(context)
- {
- var self = this;
- iterateWindows(context.browser.contentWindow, function(subwin)
- {
- self.cleanupSheets(subwin.document, context);
- });
- }
- /**/
-});
-
-// ************************************************************************************************
-
-Firebug.CSSStyleSheetPanel = function() {};
-
-Firebug.CSSStyleSheetPanel.prototype = extend(Firebug.SourceBoxPanel,
-{
- template: domplate(
- {
- tag:
- DIV({"class": "cssSheet insertInto a11yCSSView"},
- FOR("rule", "$rules",
- CSSRuleTag
- ),
- DIV({"class": "cssSheet editable insertBefore"}, "")
- )
- }),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- refresh: function()
- {
- if (this.location)
- this.updateLocation(this.location);
- else if (this.selection)
- this.updateSelection(this.selection);
- },
-
- toggleEditing: function()
- {
- if (!this.stylesheetEditor)
- this.stylesheetEditor = new StyleSheetEditor(this.document);
-
- if (this.editing)
- Firebug.Editor.stopEditing();
- else
- {
- if (!this.location)
- return;
-
- var styleSheet = this.location.editStyleSheet
- ? this.location.editStyleSheet.sheet
- : this.location;
-
- var css = getStyleSheetCSS(styleSheet, this.context);
- //var topmost = getTopmostRuleLine(this.panelNode);
-
- this.stylesheetEditor.styleSheet = this.location;
- Firebug.Editor.startEditing(this.panelNode, css, this.stylesheetEditor);
- //this.stylesheetEditor.scrollToLine(topmost.line, topmost.offset);
- }
- },
-
- getStylesheetURL: function(rule)
- {
- if (this.location.href)
- return this.location.href;
- else
- return this.context.window.location.href;
- },
-
- getRuleByLine: function(styleSheet, line)
- {
- if (!domUtils)
- return null;
-
- var cssRules = styleSheet.cssRules;
- for (var i = 0; i < cssRules.length; ++i)
- {
- var rule = cssRules[i];
- if (rule instanceof CSSStyleRule)
- {
- var ruleLine = domUtils.getRuleLine(rule);
- if (ruleLine >= line)
- return rule;
- }
- }
- },
-
- highlightRule: function(rule)
- {
- var ruleElement = Firebug.getElementByRepObject(this.panelNode.firstChild, rule);
- if (ruleElement)
- {
- scrollIntoCenterView(ruleElement, this.panelNode);
- setClassTimed(ruleElement, "jumpHighlight", this.context);
- }
- },
-
- getStyleSheetRules: function(context, styleSheet)
- {
- var isSystemSheet = isSystemStyleSheet(styleSheet);
-
- function appendRules(cssRules)
- {
- for (var i = 0; i < cssRules.length; ++i)
- {
- var rule = cssRules[i];
-
- // TODO: xxxpedro opera instanceof stylesheet remove the following comments when
- // the issue with opera and style sheet Classes has been solved.
-
- //if (rule instanceof CSSStyleRule)
- if (instanceOf(rule, "CSSStyleRule"))
- {
- var props = this.getRuleProperties(context, rule);
- //var line = domUtils.getRuleLine(rule);
- var line = null;
-
- var selector = rule.selectorText;
-
- if (isIE)
- {
- selector = selector.replace(reSelectorTag,
- function(s){return s.toLowerCase();});
- }
-
- var ruleId = rule.selectorText+"/"+line;
- rules.push({tag: CSSStyleRuleTag.tag, rule: rule, id: ruleId,
- selector: selector, props: props,
- isSystemSheet: isSystemSheet,
- isSelectorEditable: true});
- }
- //else if (rule instanceof CSSImportRule)
- else if (instanceOf(rule, "CSSImportRule"))
- rules.push({tag: CSSImportRuleTag.tag, rule: rule});
- //else if (rule instanceof CSSMediaRule)
- else if (instanceOf(rule, "CSSMediaRule"))
- appendRules.apply(this, [rule.cssRules]);
- else
- {
- if (FBTrace.DBG_ERRORS || FBTrace.DBG_CSS)
- FBTrace.sysout("css getStyleSheetRules failed to classify a rule ", rule);
- }
- }
- }
-
- var rules = [];
- appendRules.apply(this, [styleSheet.cssRules || styleSheet.rules]);
- return rules;
- },
-
- parseCSSProps: function(style, inheritMode)
- {
- var props = [];
-
- if (Firebug.expandShorthandProps)
- {
- var count = style.length-1,
- index = style.length;
- while (index--)
- {
- var propName = style.item(count - index);
- this.addProperty(propName, style.getPropertyValue(propName), !!style.getPropertyPriority(propName), false, inheritMode, props);
- }
- }
- else
- {
- var lines = style.cssText.match(/(?:[^;\(]*(?:\([^\)]*?\))?[^;\(]*)*;?/g);
- var propRE = /\s*([^:\s]*)\s*:\s*(.*?)\s*(! important)?;?$/;
- var line,i=0;
- // TODO: xxxpedro port to firebug: variable leaked into global namespace
- var m;
-
- while(line=lines[i++]){
- m = propRE.exec(line);
- if(!m)
- continue;
- //var name = m[1], value = m[2], important = !!m[3];
- if (m[2])
- this.addProperty(m[1], m[2], !!m[3], false, inheritMode, props);
- };
- }
-
- return props;
- },
-
- getRuleProperties: function(context, rule, inheritMode)
- {
- var props = this.parseCSSProps(rule.style, inheritMode);
-
- // TODO: xxxpedro port to firebug: variable leaked into global namespace
- //var line = domUtils.getRuleLine(rule);
- var line;
- var ruleId = rule.selectorText+"/"+line;
- this.addOldProperties(context, ruleId, inheritMode, props);
- sortProperties(props);
-
- return props;
- },
-
- addOldProperties: function(context, ruleId, inheritMode, props)
- {
- if (context.selectorMap && context.selectorMap.hasOwnProperty(ruleId) )
- {
- var moreProps = context.selectorMap[ruleId];
- for (var i = 0; i < moreProps.length; ++i)
- {
- var prop = moreProps[i];
- this.addProperty(prop.name, prop.value, prop.important, true, inheritMode, props);
- }
- }
- },
-
- addProperty: function(name, value, important, disabled, inheritMode, props)
- {
- name = name.toLowerCase();
-
- if (inheritMode && !inheritedStyleNames[name])
- return;
-
- name = this.translateName(name, value);
- if (name)
- {
- value = stripUnits(rgbToHex(value));
- important = important ? " !important" : "";
-
- var prop = {name: name, value: value, important: important, disabled: disabled};
- props.push(prop);
- }
- },
-
- translateName: function(name, value)
- {
- // Don't show these proprietary Mozilla properties
- if ((value == "-moz-initial"
- && (name == "-moz-background-clip" || name == "-moz-background-origin"
- || name == "-moz-background-inline-policy"))
- || (value == "physical"
- && (name == "margin-left-ltr-source" || name == "margin-left-rtl-source"
- || name == "margin-right-ltr-source" || name == "margin-right-rtl-source"))
- || (value == "physical"
- && (name == "padding-left-ltr-source" || name == "padding-left-rtl-source"
- || name == "padding-right-ltr-source" || name == "padding-right-rtl-source")))
- return null;
-
- // Translate these back to the form the user probably expects
- if (name == "margin-left-value")
- return "margin-left";
- else if (name == "margin-right-value")
- return "margin-right";
- else if (name == "margin-top-value")
- return "margin-top";
- else if (name == "margin-bottom-value")
- return "margin-bottom";
- else if (name == "padding-left-value")
- return "padding-left";
- else if (name == "padding-right-value")
- return "padding-right";
- else if (name == "padding-top-value")
- return "padding-top";
- else if (name == "padding-bottom-value")
- return "padding-bottom";
- // XXXjoe What about border!
- else
- return name;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- editElementStyle: function()
- {
- ///var rulesBox = this.panelNode.getElementsByClassName("cssElementRuleContainer")[0];
- var rulesBox = $$(".cssElementRuleContainer", this.panelNode)[0];
- var styleRuleBox = rulesBox && Firebug.getElementByRepObject(rulesBox, this.selection);
- if (!styleRuleBox)
- {
- var rule = {rule: this.selection, inherited: false, selector: "element.style", props: []};
- if (!rulesBox)
- {
- // The element did not have any displayed styles. We need to create the whole tree and remove
- // the no styles message
- styleRuleBox = this.template.cascadedTag.replace({
- rules: [rule], inherited: [], inheritLabel: "Inherited from" // $STR("InheritedFrom")
- }, this.panelNode);
-
- ///styleRuleBox = styleRuleBox.getElementsByClassName("cssElementRuleContainer")[0];
- styleRuleBox = $$(".cssElementRuleContainer", styleRuleBox)[0];
- }
- else
- styleRuleBox = this.template.ruleTag.insertBefore({rule: rule}, rulesBox);
-
- ///styleRuleBox = styleRuleBox.getElementsByClassName("insertInto")[0];
- styleRuleBox = $$(".insertInto", styleRuleBox)[0];
- }
-
- Firebug.Editor.insertRowForObject(styleRuleBox);
- },
-
- insertPropertyRow: function(row)
- {
- Firebug.Editor.insertRowForObject(row);
- },
-
- insertRule: function(row)
- {
- var location = getAncestorByClass(row, "cssRule");
- if (!location)
- {
- location = getChildByClass(this.panelNode, "cssSheet");
- Firebug.Editor.insertRowForObject(location);
- }
- else
- {
- Firebug.Editor.insertRow(location, "before");
- }
- },
-
- editPropertyRow: function(row)
- {
- var propValueBox = getChildByClass(row, "cssPropValue");
- Firebug.Editor.startEditing(propValueBox);
- },
-
- deletePropertyRow: function(row)
- {
- var rule = Firebug.getRepObject(row);
- var propName = getChildByClass(row, "cssPropName")[textContent];
- Firebug.CSSModule.removeProperty(rule, propName);
-
- // Remove the property from the selector map, if it was disabled
- var ruleId = Firebug.getRepNode(row).getAttribute("ruleId");
- if ( this.context.selectorMap && this.context.selectorMap.hasOwnProperty(ruleId) )
- {
- var map = this.context.selectorMap[ruleId];
- for (var i = 0; i < map.length; ++i)
- {
- if (map[i].name == propName)
- {
- map.splice(i, 1);
- break;
- }
- }
- }
- if (this.name == "stylesheet")
- dispatch([Firebug.A11yModel], 'onInlineEditorClose', [this, row.firstChild, true]);
- row.parentNode.removeChild(row);
-
- this.markChange(this.name == "stylesheet");
- },
-
- disablePropertyRow: function(row)
- {
- toggleClass(row, "disabledStyle");
-
- var rule = Firebug.getRepObject(row);
- var propName = getChildByClass(row, "cssPropName")[textContent];
-
- if (!this.context.selectorMap)
- this.context.selectorMap = {};
-
- // XXXjoe Generate unique key for elements too
- var ruleId = Firebug.getRepNode(row).getAttribute("ruleId");
- if (!(this.context.selectorMap.hasOwnProperty(ruleId)))
- this.context.selectorMap[ruleId] = [];
-
- var map = this.context.selectorMap[ruleId];
- var propValue = getChildByClass(row, "cssPropValue")[textContent];
- var parsedValue = parsePriority(propValue);
- if (hasClass(row, "disabledStyle"))
- {
- Firebug.CSSModule.removeProperty(rule, propName);
-
- map.push({"name": propName, "value": parsedValue.value,
- "important": parsedValue.priority});
- }
- else
- {
- Firebug.CSSModule.setProperty(rule, propName, parsedValue.value, parsedValue.priority);
-
- var index = findPropByName(map, propName);
- map.splice(index, 1);
- }
-
- this.markChange(this.name == "stylesheet");
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- onMouseDown: function(event)
- {
- //console.log("onMouseDown", event.target || event.srcElement, event);
-
- // xxxpedro adjusting coordinates because the panel isn't a window yet
- var offset = event.clientX - this.panelNode.parentNode.offsetLeft;
-
- // XXjoe Hack to only allow clicking on the checkbox
- if (!isLeftClick(event) || offset > 20)
- return;
-
- var target = event.target || event.srcElement;
- if (hasClass(target, "textEditor"))
- return;
-
- var row = getAncestorByClass(target, "cssProp");
- if (row && hasClass(row, "editGroup"))
- {
- this.disablePropertyRow(row);
- cancelEvent(event);
- }
- },
-
- onDoubleClick: function(event)
- {
- //console.log("onDoubleClick", event.target || event.srcElement, event);
-
- // xxxpedro adjusting coordinates because the panel isn't a window yet
- var offset = event.clientX - this.panelNode.parentNode.offsetLeft;
-
- if (!isLeftClick(event) || offset <= 20)
- return;
-
- var target = event.target || event.srcElement;
-
- //console.log("ok", target, hasClass(target, "textEditorInner"), !isLeftClick(event), offset <= 20);
-
- // if the inline editor was clicked, don't insert a new rule
- if (hasClass(target, "textEditorInner"))
- return;
-
- var row = getAncestorByClass(target, "cssRule");
- if (row && !getAncestorByClass(target, "cssPropName")
- && !getAncestorByClass(target, "cssPropValue"))
- {
- this.insertPropertyRow(row);
- cancelEvent(event);
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // extends Panel
-
- name: "stylesheet",
- title: "CSS",
- parentPanel: null,
- searchable: true,
- dependents: ["css", "stylesheet", "dom", "domSide", "layout"],
-
- options:
- {
- hasToolButtons: true
- },
-
- create: function()
- {
- Firebug.Panel.create.apply(this, arguments);
-
- this.onMouseDown = bind(this.onMouseDown, this);
- this.onDoubleClick = bind(this.onDoubleClick, this);
-
- if (this.name == "stylesheet")
- {
- this.onChangeSelect = bind(this.onChangeSelect, this);
-
- var doc = Firebug.browser.document;
- var selectNode = this.selectNode = createElement("select");
-
- CssAnalyzer.processAllStyleSheets(doc, function(doc, styleSheet)
- {
- var key = StyleSheetCache.key(styleSheet);
- var fileName = getFileName(styleSheet.href) || getFileName(doc.location.href);
- var option = createElement("option", {value: key});
-
- option.appendChild(Firebug.chrome.document.createTextNode(fileName));
- selectNode.appendChild(option);
- });
-
- this.toolButtonsNode.appendChild(selectNode);
- }
- /**/
- },
-
- onChangeSelect: function(event)
- {
- event = event || window.event;
- var target = event.srcElement || event.currentTarget;
- var key = target.value;
- var styleSheet = StyleSheetCache.get(key);
-
- this.updateLocation(styleSheet);
- },
-
- initialize: function()
- {
- Firebug.Panel.initialize.apply(this, arguments);
-
- //if (!domUtils)
- //{
- // try {
- // domUtils = CCSV("@mozilla.org/inspector/dom-utils;1", "inIDOMUtils");
- // } catch (exc) {
- // if (FBTrace.DBG_ERRORS)
- // FBTrace.sysout("@mozilla.org/inspector/dom-utils;1 FAILED to load: "+exc, exc);
- // }
- //}
-
- //TODO: xxxpedro
- this.context = Firebug.chrome; // TODO: xxxpedro css2
- this.document = Firebug.chrome.document; // TODO: xxxpedro css2
-
- this.initializeNode();
-
- if (this.name == "stylesheet")
- {
- var styleSheets = Firebug.browser.document.styleSheets;
-
- if (styleSheets.length > 0)
- {
- addEvent(this.selectNode, "change", this.onChangeSelect);
-
- this.updateLocation(styleSheets[0]);
- }
- }
-
- //Firebug.SourceBoxPanel.initialize.apply(this, arguments);
- },
-
- shutdown: function()
- {
- // must destroy the editor when we leave the panel to avoid problems (Issue 2981)
- Firebug.Editor.stopEditing();
-
- if (this.name == "stylesheet")
- {
- removeEvent(this.selectNode, "change", this.onChangeSelect);
- }
-
- this.destroyNode();
-
- Firebug.Panel.shutdown.apply(this, arguments);
- },
-
- destroy: function(state)
- {
- //state.scrollTop = this.panelNode.scrollTop ? this.panelNode.scrollTop : this.lastScrollTop;
-
- //persistObjects(this, state);
-
- // xxxpedro we are stopping the editor in the shutdown method already
- //Firebug.Editor.stopEditing();
- Firebug.Panel.destroy.apply(this, arguments);
- },
-
- initializeNode: function(oldPanelNode)
- {
- addEvent(this.panelNode, "mousedown", this.onMouseDown);
- addEvent(this.panelNode, "dblclick", this.onDoubleClick);
- //Firebug.SourceBoxPanel.initializeNode.apply(this, arguments);
- //dispatch([Firebug.A11yModel], 'onInitializeNode', [this, 'css']);
- },
-
- destroyNode: function()
- {
- removeEvent(this.panelNode, "mousedown", this.onMouseDown);
- removeEvent(this.panelNode, "dblclick", this.onDoubleClick);
- //Firebug.SourceBoxPanel.destroyNode.apply(this, arguments);
- //dispatch([Firebug.A11yModel], 'onDestroyNode', [this, 'css']);
- },
-
- ishow: function(state)
- {
- Firebug.Inspector.stopInspecting(true);
-
- this.showToolbarButtons("fbCSSButtons", true);
-
- if (this.context.loaded && !this.location) // wait for loadedContext to restore the panel
- {
- restoreObjects(this, state);
-
- if (!this.location)
- this.location = this.getDefaultLocation();
-
- if (state && state.scrollTop)
- this.panelNode.scrollTop = state.scrollTop;
- }
- },
-
- ihide: function()
- {
- this.showToolbarButtons("fbCSSButtons", false);
-
- this.lastScrollTop = this.panelNode.scrollTop;
- },
-
- supportsObject: function(object)
- {
- if (object instanceof CSSStyleSheet)
- return 1;
- else if (object instanceof CSSStyleRule)
- return 2;
- else if (object instanceof CSSStyleDeclaration)
- return 2;
- else if (object instanceof SourceLink && object.type == "css" && reCSS.test(object.href))
- return 2;
- else
- return 0;
- },
-
- updateLocation: function(styleSheet)
- {
- if (!styleSheet)
- return;
- if (styleSheet.editStyleSheet)
- styleSheet = styleSheet.editStyleSheet.sheet;
-
- // if it is a restricted stylesheet, show the warning message and abort the update process
- if (styleSheet.restricted)
- {
- FirebugReps.Warning.tag.replace({object: "AccessRestricted"}, this.panelNode);
-
- // TODO: xxxpedro remove when there the external resource problem is fixed
- CssAnalyzer.externalStyleSheetWarning.tag.append({
- object: "The stylesheet could not be loaded due to access restrictions. ",
- link: "more...",
- href: "http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22Access_to_restricted_URI_denied.22"
- }, this.panelNode);
-
- return;
- }
-
- var rules = this.getStyleSheetRules(this.context, styleSheet);
-
- var result;
- if (rules.length)
- // FIXME xxxpedro chromenew this is making iPad's Safari to crash
- result = this.template.tag.replace({rules: rules}, this.panelNode);
- else
- result = FirebugReps.Warning.tag.replace({object: "EmptyStyleSheet"}, this.panelNode);
-
- // TODO: xxxpedro need to fix showToolbarButtons function
- //this.showToolbarButtons("fbCSSButtons", !isSystemStyleSheet(this.location));
-
- //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, this.panelNode]);
- },
-
- updateSelection: function(object)
- {
- this.selection = null;
-
- if (object instanceof CSSStyleDeclaration) {
- object = object.parentRule;
- }
-
- if (object instanceof CSSStyleRule)
- {
- this.navigate(object.parentStyleSheet);
- this.highlightRule(object);
- }
- else if (object instanceof CSSStyleSheet)
- {
- this.navigate(object);
- }
- else if (object instanceof SourceLink)
- {
- try
- {
- var sourceLink = object;
-
- var sourceFile = getSourceFileByHref(sourceLink.href, this.context);
- if (sourceFile)
- {
- clearNode(this.panelNode); // replace rendered stylesheets
- this.showSourceFile(sourceFile);
-
- var lineNo = object.line;
- if (lineNo)
- this.scrollToLine(lineNo, this.jumpHighlightFactory(lineNo, this.context));
- }
- else // XXXjjb we should not be taking this path
- {
- var stylesheet = getStyleSheetByHref(sourceLink.href, this.context);
- if (stylesheet)
- this.navigate(stylesheet);
- else
- {
- if (FBTrace.DBG_CSS)
- FBTrace.sysout("css.updateSelection no sourceFile for "+sourceLink.href, sourceLink);
- }
- }
- }
- catch(exc) {
- if (FBTrace.DBG_CSS)
- FBTrace.sysout("css.upDateSelection FAILS "+exc, exc);
- }
- }
- },
-
- updateOption: function(name, value)
- {
- if (name == "expandShorthandProps")
- this.refresh();
- },
-
- getLocationList: function()
- {
- var styleSheets = getAllStyleSheets(this.context);
- return styleSheets;
- },
-
- getOptionsMenuItems: function()
- {
- return [
- {label: "Expand Shorthand Properties", type: "checkbox", checked: Firebug.expandShorthandProps,
- command: bindFixed(Firebug.togglePref, Firebug, "expandShorthandProps") },
- "-",
- {label: "Refresh", command: bind(this.refresh, this) }
- ];
- },
-
- getContextMenuItems: function(style, target)
- {
- var items = [];
-
- if (this.infoTipType == "color")
- {
- items.push(
- {label: "CopyColor",
- command: bindFixed(copyToClipboard, FBL, this.infoTipObject) }
- );
- }
- else if (this.infoTipType == "image")
- {
- items.push(
- {label: "CopyImageLocation",
- command: bindFixed(copyToClipboard, FBL, this.infoTipObject) },
- {label: "OpenImageInNewTab",
- command: bindFixed(openNewTab, FBL, this.infoTipObject) }
- );
- }
-
- ///if (this.selection instanceof Element)
- if (isElement(this.selection))
- {
- items.push(
- //"-",
- {label: "EditStyle",
- command: bindFixed(this.editElementStyle, this) }
- );
- }
- else if (!isSystemStyleSheet(this.selection))
- {
- items.push(
- //"-",
- {label: "NewRule",
- command: bindFixed(this.insertRule, this, target) }
- );
- }
-
- var cssRule = getAncestorByClass(target, "cssRule");
- if (cssRule && hasClass(cssRule, "cssEditableRule"))
- {
- items.push(
- "-",
- {label: "NewProp",
- command: bindFixed(this.insertPropertyRow, this, target) }
- );
-
- var propRow = getAncestorByClass(target, "cssProp");
- if (propRow)
- {
- var propName = getChildByClass(propRow, "cssPropName")[textContent];
- var isDisabled = hasClass(propRow, "disabledStyle");
-
- items.push(
- {label: $STRF("EditProp", [propName]), nol10n: true,
- command: bindFixed(this.editPropertyRow, this, propRow) },
- {label: $STRF("DeleteProp", [propName]), nol10n: true,
- command: bindFixed(this.deletePropertyRow, this, propRow) },
- {label: $STRF("DisableProp", [propName]), nol10n: true,
- type: "checkbox", checked: isDisabled,
- command: bindFixed(this.disablePropertyRow, this, propRow) }
- );
- }
- }
-
- items.push(
- "-",
- {label: "Refresh", command: bind(this.refresh, this) }
- );
-
- return items;
- },
-
- browseObject: function(object)
- {
- if (this.infoTipType == "image")
- {
- openNewTab(this.infoTipObject);
- return true;
- }
- },
-
- showInfoTip: function(infoTip, target, x, y)
- {
- var propValue = getAncestorByClass(target, "cssPropValue");
- if (propValue)
- {
- var offset = getClientOffset(propValue);
- var offsetX = x-offset.x;
-
- var text = propValue[textContent];
- var charWidth = propValue.offsetWidth/text.length;
- var charOffset = Math.floor(offsetX/charWidth);
-
- var cssValue = parseCSSValue(text, charOffset);
- if (cssValue)
- {
- if (cssValue.value == this.infoTipValue)
- return true;
-
- this.infoTipValue = cssValue.value;
-
- if (cssValue.type == "rgb" || (!cssValue.type && isColorKeyword(cssValue.value)))
- {
- this.infoTipType = "color";
- this.infoTipObject = cssValue.value;
-
- return Firebug.InfoTip.populateColorInfoTip(infoTip, cssValue.value);
- }
- else if (cssValue.type == "url")
- {
- ///var propNameNode = target.parentNode.getElementsByClassName("cssPropName").item(0);
- var propNameNode = getElementByClass(target.parentNode, "cssPropName");
- if (propNameNode && isImageRule(propNameNode[textContent]))
- {
- var rule = Firebug.getRepObject(target);
- var baseURL = this.getStylesheetURL(rule);
- var relURL = parseURLValue(cssValue.value);
- var absURL = isDataURL(relURL) ? relURL:absoluteURL(relURL, baseURL);
- var repeat = parseRepeatValue(text);
-
- this.infoTipType = "image";
- this.infoTipObject = absURL;
-
- return Firebug.InfoTip.populateImageInfoTip(infoTip, absURL, repeat);
- }
- }
- }
- }
-
- delete this.infoTipType;
- delete this.infoTipValue;
- delete this.infoTipObject;
- },
-
- getEditor: function(target, value)
- {
- if (target == this.panelNode
- || hasClass(target, "cssSelector") || hasClass(target, "cssRule")
- || hasClass(target, "cssSheet"))
- {
- if (!this.ruleEditor)
- this.ruleEditor = new CSSRuleEditor(this.document);
-
- return this.ruleEditor;
- }
- else
- {
- if (!this.editor)
- this.editor = new CSSEditor(this.document);
-
- return this.editor;
- }
- },
-
- getDefaultLocation: function()
- {
- try
- {
- var styleSheets = this.context.window.document.styleSheets;
- if (styleSheets.length)
- {
- var sheet = styleSheets[0];
- return (Firebug.filterSystemURLs && isSystemURL(getURLForStyleSheet(sheet))) ? null : sheet;
- }
- }
- catch (exc)
- {
- if (FBTrace.DBG_LOCATIONS)
- FBTrace.sysout("css.getDefaultLocation FAILS "+exc, exc);
- }
- },
-
- getObjectDescription: function(styleSheet)
- {
- var url = getURLForStyleSheet(styleSheet);
- var instance = getInstanceForStyleSheet(styleSheet);
-
- var baseDescription = splitURLBase(url);
- if (instance) {
- baseDescription.name = baseDescription.name + " #" + (instance + 1);
- }
- return baseDescription;
- },
-
- search: function(text, reverse)
- {
- var curDoc = this.searchCurrentDoc(!Firebug.searchGlobal, text, reverse);
- if (!curDoc && Firebug.searchGlobal)
- {
- return this.searchOtherDocs(text, reverse);
- }
- return curDoc;
- },
-
- searchOtherDocs: function(text, reverse)
- {
- var scanRE = Firebug.Search.getTestingRegex(text);
- function scanDoc(styleSheet) {
- // we don't care about reverse here as we are just looking for existence,
- // if we do have a result we will handle the reverse logic on display
- for (var i = 0; i < styleSheet.cssRules.length; i++)
- {
- if (scanRE.test(styleSheet.cssRules[i].cssText))
- {
- return true;
- }
- }
- }
-
- if (this.navigateToNextDocument(scanDoc, reverse))
- {
- return this.searchCurrentDoc(true, text, reverse);
- }
- },
-
- searchCurrentDoc: function(wrapSearch, text, reverse)
- {
- if (!text)
- {
- delete this.currentSearch;
- return false;
- }
-
- var row;
- if (this.currentSearch && text == this.currentSearch.text)
- {
- row = this.currentSearch.findNext(wrapSearch, false, reverse, Firebug.Search.isCaseSensitive(text));
- }
- else
- {
- if (this.editing)
- {
- this.currentSearch = new TextSearch(this.stylesheetEditor.box);
- row = this.currentSearch.find(text, reverse, Firebug.Search.isCaseSensitive(text));
-
- if (row)
- {
- var sel = this.document.defaultView.getSelection();
- sel.removeAllRanges();
- sel.addRange(this.currentSearch.range);
- scrollSelectionIntoView(this);
- return true;
- }
- else
- return false;
- }
- else
- {
- function findRow(node) { return node.nodeType == 1 ? node : node.parentNode; }
- this.currentSearch = new TextSearch(this.panelNode, findRow);
- row = this.currentSearch.find(text, reverse, Firebug.Search.isCaseSensitive(text));
- }
- }
-
- if (row)
- {
- this.document.defaultView.getSelection().selectAllChildren(row);
- scrollIntoCenterView(row, this.panelNode);
- dispatch([Firebug.A11yModel], 'onCSSSearchMatchFound', [this, text, row]);
- return true;
- }
- else
- {
- dispatch([Firebug.A11yModel], 'onCSSSearchMatchFound', [this, text, null]);
- return false;
- }
- },
-
- getSearchOptionsMenuItems: function()
- {
- return [
- Firebug.Search.searchOptionMenu("search.Case_Sensitive", "searchCaseSensitive"),
- Firebug.Search.searchOptionMenu("search.Multiple_Files", "searchGlobal")
- ];
- }
-});
-/**/
-// ************************************************************************************************
-
-function CSSElementPanel() {}
-
-CSSElementPanel.prototype = extend(Firebug.CSSStyleSheetPanel.prototype,
-{
- template: domplate(
- {
- cascadedTag:
- DIV({"class": "a11yCSSView", role : 'presentation'},
- DIV({role : 'list', 'aria-label' : $STR('aria.labels.style rules') },
- FOR("rule", "$rules",
- TAG("$ruleTag", {rule: "$rule"})
- )
- ),
- DIV({role : "list", 'aria-label' :$STR('aria.labels.inherited style rules')},
- FOR("section", "$inherited",
- H1({"class": "cssInheritHeader groupHeader focusRow", role : 'listitem' },
- SPAN({"class": "cssInheritLabel"}, "$inheritLabel"),
- TAG(FirebugReps.Element.shortTag, {object: "$section.element"})
- ),
- DIV({role : 'group'},
- FOR("rule", "$section.rules",
- TAG("$ruleTag", {rule: "$rule"})
- )
- )
- )
- )
- ),
-
- ruleTag:
- isIE ?
- // IE needs the sourceLink first, otherwise it will be rendered outside the panel
- DIV({"class": "cssElementRuleContainer"},
- TAG(FirebugReps.SourceLink.tag, {object: "$rule.sourceLink"}),
- TAG(CSSStyleRuleTag.tag, {rule: "$rule"})
- )
- :
- // other browsers need the sourceLink last, otherwise it will cause an extra space
- // before the rule representation
- DIV({"class": "cssElementRuleContainer"},
- TAG(CSSStyleRuleTag.tag, {rule: "$rule"}),
- TAG(FirebugReps.SourceLink.tag, {object: "$rule.sourceLink"})
- )
- }),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- updateCascadeView: function(element)
- {
- //dispatch([Firebug.A11yModel], 'onBeforeCSSRulesAdded', [this]);
- var rules = [], sections = [], usedProps = {};
- this.getInheritedRules(element, sections, usedProps);
- this.getElementRules(element, rules, usedProps);
-
- if (rules.length || sections.length)
- {
- var inheritLabel = "Inherited from"; // $STR("InheritedFrom");
- var result = this.template.cascadedTag.replace({rules: rules, inherited: sections,
- inheritLabel: inheritLabel}, this.panelNode);
- //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]);
- }
- else
- {
- var result = FirebugReps.Warning.tag.replace({object: "EmptyElementCSS"}, this.panelNode);
- //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]);
- }
-
- // TODO: xxxpedro remove when there the external resource problem is fixed
- if (CssAnalyzer.hasExternalStyleSheet())
- CssAnalyzer.externalStyleSheetWarning.tag.append({
- object: "The results here may be inaccurate because some " +
- "stylesheets could not be loaded due to access restrictions. ",
- link: "more...",
- href: "http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22This_element_has_no_style_rules.22"
- }, this.panelNode);
- },
-
- getStylesheetURL: function(rule)
- {
- // if the parentStyleSheet.href is null, CSS std says its inline style.
- // TODO: xxxpedro IE doesn't have rule.parentStyleSheet so we must fall back to the doc.location
- if (rule && rule.parentStyleSheet && rule.parentStyleSheet.href)
- return rule.parentStyleSheet.href;
- else
- return this.selection.ownerDocument.location.href;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- getInheritedRules: function(element, sections, usedProps)
- {
- var parent = element.parentNode;
- if (parent && parent.nodeType == 1)
- {
- this.getInheritedRules(parent, sections, usedProps);
-
- var rules = [];
- this.getElementRules(parent, rules, usedProps, true);
-
- if (rules.length)
- sections.splice(0, 0, {element: parent, rules: rules});
- }
- },
-
- getElementRules: function(element, rules, usedProps, inheritMode)
- {
- var inspectedRules, displayedRules = {};
-
- inspectedRules = CssAnalyzer.getElementCSSRules(element);
-
- if (inspectedRules)
- {
- for (var i = 0, length=inspectedRules.length; i < length; ++i)
- {
- var ruleId = inspectedRules[i];
- var ruleData = CssAnalyzer.getRuleData(ruleId);
- var rule = ruleData.rule;
-
- var ssid = ruleData.styleSheetId;
- var parentStyleSheet = StyleSheetCache.get(ssid);
-
- var href = parentStyleSheet.externalURL ? parentStyleSheet.externalURL : parentStyleSheet.href; // Null means inline
-
- var instance = null;
- //var instance = getInstanceForStyleSheet(rule.parentStyleSheet, element.ownerDocument);
-
- var isSystemSheet = false;
- //var isSystemSheet = isSystemStyleSheet(rule.parentStyleSheet);
-
- if (!Firebug.showUserAgentCSS && isSystemSheet) // This removes user agent rules
- continue;
-
- if (!href)
- href = element.ownerDocument.location.href; // http://code.google.com/p/fbug/issues/detail?id=452
-
- var props = this.getRuleProperties(this.context, rule, inheritMode);
- if (inheritMode && !props.length)
- continue;
-
- //
- //var line = domUtils.getRuleLine(rule);
- // TODO: xxxpedro CSS line number
- var line = ruleData.lineNo;
-
- var ruleId = rule.selectorText+"/"+line;
- var sourceLink = new SourceLink(href, line, "css", rule, instance);
-
- this.markOverridenProps(props, usedProps, inheritMode);
-
- rules.splice(0, 0, {rule: rule, id: ruleId,
- selector: ruleData.selector, sourceLink: sourceLink,
- props: props, inherited: inheritMode,
- isSystemSheet: isSystemSheet});
- }
- }
-
- if (element.style)
- this.getStyleProperties(element, rules, usedProps, inheritMode);
-
- if (FBTrace.DBG_CSS)
- FBTrace.sysout("getElementRules "+rules.length+" rules for "+getElementXPath(element), rules);
- },
- /*
- getElementRules: function(element, rules, usedProps, inheritMode)
- {
- var inspectedRules, displayedRules = {};
- try
- {
- inspectedRules = domUtils ? domUtils.getCSSStyleRules(element) : null;
- } catch (exc) {}
-
- if (inspectedRules)
- {
- for (var i = 0; i < inspectedRules.Count(); ++i)
- {
- var rule = QI(inspectedRules.GetElementAt(i), nsIDOMCSSStyleRule);
-
- var href = rule.parentStyleSheet.href; // Null means inline
-
- var instance = getInstanceForStyleSheet(rule.parentStyleSheet, element.ownerDocument);
-
- var isSystemSheet = isSystemStyleSheet(rule.parentStyleSheet);
- if (!Firebug.showUserAgentCSS && isSystemSheet) // This removes user agent rules
- continue;
- if (!href)
- href = element.ownerDocument.location.href; // http://code.google.com/p/fbug/issues/detail?id=452
-
- var props = this.getRuleProperties(this.context, rule, inheritMode);
- if (inheritMode && !props.length)
- continue;
-
- var line = domUtils.getRuleLine(rule);
- var ruleId = rule.selectorText+"/"+line;
- var sourceLink = new SourceLink(href, line, "css", rule, instance);
-
- this.markOverridenProps(props, usedProps, inheritMode);
-
- rules.splice(0, 0, {rule: rule, id: ruleId,
- selector: rule.selectorText, sourceLink: sourceLink,
- props: props, inherited: inheritMode,
- isSystemSheet: isSystemSheet});
- }
- }
-
- if (element.style)
- this.getStyleProperties(element, rules, usedProps, inheritMode);
-
- if (FBTrace.DBG_CSS)
- FBTrace.sysout("getElementRules "+rules.length+" rules for "+getElementXPath(element), rules);
- },
- /**/
- markOverridenProps: function(props, usedProps, inheritMode)
- {
- for (var i = 0; i < props.length; ++i)
- {
- var prop = props[i];
- if ( usedProps.hasOwnProperty(prop.name) )
- {
- var deadProps = usedProps[prop.name]; // all previous occurrences of this property
- for (var j = 0; j < deadProps.length; ++j)
- {
- var deadProp = deadProps[j];
- if (!deadProp.disabled && !deadProp.wasInherited && deadProp.important && !prop.important)
- prop.overridden = true; // new occurrence overridden
- else if (!prop.disabled)
- deadProp.overridden = true; // previous occurrences overridden
- }
- }
- else
- usedProps[prop.name] = [];
-
- prop.wasInherited = inheritMode ? true : false;
- usedProps[prop.name].push(prop); // all occurrences of a property seen so far, by name
- }
- },
-
- getStyleProperties: function(element, rules, usedProps, inheritMode)
- {
- var props = this.parseCSSProps(element.style, inheritMode);
- this.addOldProperties(this.context, getElementXPath(element), inheritMode, props);
-
- sortProperties(props);
- this.markOverridenProps(props, usedProps, inheritMode);
-
- if (props.length)
- rules.splice(0, 0,
- {rule: element, id: getElementXPath(element),
- selector: "element.style", props: props, inherited: inheritMode});
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // extends Panel
-
- name: "css",
- title: "Style",
- parentPanel: "HTML",
- order: 0,
-
- initialize: function()
- {
- this.context = Firebug.chrome; // TODO: xxxpedro css2
- this.document = Firebug.chrome.document; // TODO: xxxpedro css2
-
- Firebug.CSSStyleSheetPanel.prototype.initialize.apply(this, arguments);
-
- // TODO: xxxpedro css2
- var selection = ElementCache.get(Firebug.context.persistedState.selectedHTMLElementId);
- if (selection)
- this.select(selection, true);
-
- //this.updateCascadeView(document.getElementsByTagName("h1")[0]);
- //this.updateCascadeView(document.getElementById("build"));
-
- /*
- this.onStateChange = bindFixed(this.contentStateCheck, this);
- this.onHoverChange = bindFixed(this.contentStateCheck, this, STATE_HOVER);
- this.onActiveChange = bindFixed(this.contentStateCheck, this, STATE_ACTIVE);
- /**/
- },
-
- ishow: function(state)
- {
- },
-
- watchWindow: function(win)
- {
- if (domUtils)
- {
- // Normally these would not be required, but in order to update after the state is set
- // using the options menu we need to monitor these global events as well
- var doc = win.document;
- ///addEvent(doc, "mouseover", this.onHoverChange);
- ///addEvent(doc, "mousedown", this.onActiveChange);
- }
- },
- unwatchWindow: function(win)
- {
- var doc = win.document;
- ///removeEvent(doc, "mouseover", this.onHoverChange);
- ///removeEvent(doc, "mousedown", this.onActiveChange);
-
- if (isAncestor(this.stateChangeEl, doc))
- {
- this.removeStateChangeHandlers();
- }
- },
-
- supportsObject: function(object)
- {
- return object instanceof Element ? 1 : 0;
- },
-
- updateView: function(element)
- {
- this.updateCascadeView(element);
- if (domUtils)
- {
- this.contentState = safeGetContentState(element);
- this.addStateChangeHandlers(element);
- }
- },
-
- updateSelection: function(element)
- {
- if ( !instanceOf(element , "Element") ) // html supports SourceLink
- return;
-
- if (sothinkInstalled)
- {
- FirebugReps.Warning.tag.replace({object: "SothinkWarning"}, this.panelNode);
- return;
- }
-
- /*
- if (!domUtils)
- {
- FirebugReps.Warning.tag.replace({object: "DOMInspectorWarning"}, this.panelNode);
- return;
- }
- /**/
-
- if (!element)
- return;
-
- this.updateView(element);
- },
-
- updateOption: function(name, value)
- {
- if (name == "showUserAgentCSS" || name == "expandShorthandProps")
- this.refresh();
- },
-
- getOptionsMenuItems: function()
- {
- var ret = [
- {label: "Show User Agent CSS", type: "checkbox", checked: Firebug.showUserAgentCSS,
- command: bindFixed(Firebug.togglePref, Firebug, "showUserAgentCSS") },
- {label: "Expand Shorthand Properties", type: "checkbox", checked: Firebug.expandShorthandProps,
- command: bindFixed(Firebug.togglePref, Firebug, "expandShorthandProps") }
- ];
- if (domUtils && this.selection)
- {
- var state = safeGetContentState(this.selection);
-
- ret.push("-");
- ret.push({label: ":active", type: "checkbox", checked: state & STATE_ACTIVE,
- command: bindFixed(this.updateContentState, this, STATE_ACTIVE, state & STATE_ACTIVE)});
- ret.push({label: ":hover", type: "checkbox", checked: state & STATE_HOVER,
- command: bindFixed(this.updateContentState, this, STATE_HOVER, state & STATE_HOVER)});
- }
- return ret;
- },
-
- updateContentState: function(state, remove)
- {
- domUtils.setContentState(remove ? this.selection.ownerDocument.documentElement : this.selection, state);
- this.refresh();
- },
-
- addStateChangeHandlers: function(el)
- {
- this.removeStateChangeHandlers();
-
- /*
- addEvent(el, "focus", this.onStateChange);
- addEvent(el, "blur", this.onStateChange);
- addEvent(el, "mouseup", this.onStateChange);
- addEvent(el, "mousedown", this.onStateChange);
- addEvent(el, "mouseover", this.onStateChange);
- addEvent(el, "mouseout", this.onStateChange);
- /**/
-
- this.stateChangeEl = el;
- },
-
- removeStateChangeHandlers: function()
- {
- var sel = this.stateChangeEl;
- if (sel)
- {
- /*
- removeEvent(sel, "focus", this.onStateChange);
- removeEvent(sel, "blur", this.onStateChange);
- removeEvent(sel, "mouseup", this.onStateChange);
- removeEvent(sel, "mousedown", this.onStateChange);
- removeEvent(sel, "mouseover", this.onStateChange);
- removeEvent(sel, "mouseout", this.onStateChange);
- /**/
- }
- },
-
- contentStateCheck: function(state)
- {
- if (!state || this.contentState & state)
- {
- var timeoutRunner = bindFixed(function()
- {
- var newState = safeGetContentState(this.selection);
- if (newState != this.contentState)
- {
- this.context.invalidatePanels(this.name);
- }
- }, this);
-
- // Delay exec until after the event has processed and the state has been updated
- setTimeout(timeoutRunner, 0);
- }
- }
-});
-
-function safeGetContentState(selection)
-{
- try
- {
- return domUtils.getContentState(selection);
- }
- catch (e)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("css.safeGetContentState; EXCEPTION", e);
- }
-}
-
-// ************************************************************************************************
-
-function CSSComputedElementPanel() {}
-
-CSSComputedElementPanel.prototype = extend(CSSElementPanel.prototype,
-{
- template: domplate(
- {
- computedTag:
- DIV({"class": "a11yCSSView", role : "list", "aria-label" : $STR('aria.labels.computed styles')},
- FOR("group", "$groups",
- H1({"class": "cssInheritHeader groupHeader focusRow", role : "listitem"},
- SPAN({"class": "cssInheritLabel"}, "$group.title")
- ),
- TABLE({width: "100%", role : 'group'},
- TBODY({role : 'presentation'},
- FOR("prop", "$group.props",
- TR({"class": 'focusRow computedStyleRow', role : 'listitem'},
- TD({"class": "stylePropName", role : 'presentation'}, "$prop.name"),
- TD({"class": "stylePropValue", role : 'presentation'}, "$prop.value")
- )
- )
- )
- )
- )
- )
- }),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- updateComputedView: function(element)
- {
- var win = isIE ?
- element.ownerDocument.parentWindow :
- element.ownerDocument.defaultView;
-
- var style = isIE ?
- element.currentStyle :
- win.getComputedStyle(element, "");
-
- var groups = [];
-
- for (var groupName in styleGroups)
- {
- // TODO: xxxpedro i18n $STR
- //var title = $STR("StyleGroup-" + groupName);
- var title = styleGroupTitles[groupName];
- var group = {title: title, props: []};
- groups.push(group);
-
- var props = styleGroups[groupName];
- for (var i = 0; i < props.length; ++i)
- {
- var propName = props[i];
- var propValue = style.getPropertyValue ?
- style.getPropertyValue(propName) :
- ""+style[toCamelCase(propName)];
-
- if (propValue === undefined || propValue === null)
- continue;
-
- propValue = stripUnits(rgbToHex(propValue));
- if (propValue)
- group.props.push({name: propName, value: propValue});
- }
- }
-
- var result = this.template.computedTag.replace({groups: groups}, this.panelNode);
- //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // extends Panel
-
- name: "computed",
- title: "Computed",
- parentPanel: "HTML",
- order: 1,
-
- updateView: function(element)
- {
- this.updateComputedView(element);
- },
-
- getOptionsMenuItems: function()
- {
- return [
- {label: "Refresh", command: bind(this.refresh, this) }
- ];
- }
-});
-
-// ************************************************************************************************
-// CSSEditor
-
-function CSSEditor(doc)
-{
- this.initializeInline(doc);
-}
-
-CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype,
-{
- insertNewRow: function(target, insertWhere)
- {
- var rule = Firebug.getRepObject(target);
- var emptyProp =
- {
- // TODO: xxxpedro - uses charCode(255) to force the element being rendered,
- // allowing webkit to get the correct position of the property name "span",
- // when inserting a new CSS rule?
- name: "",
- value: "",
- important: ""
- };
-
- if (insertWhere == "before")
- return CSSPropTag.tag.insertBefore({prop: emptyProp, rule: rule}, target);
- else
- return CSSPropTag.tag.insertAfter({prop: emptyProp, rule: rule}, target);
- },
-
- saveEdit: function(target, value, previousValue)
- {
- // We need to check the value first in order to avoid a problem in IE8
- // See Issue 3038: Empty (null) styles when adding CSS styles in Firebug Lite
- if (!value) return;
-
- target.innerHTML = escapeForCss(value);
-
- var row = getAncestorByClass(target, "cssProp");
- if (hasClass(row, "disabledStyle"))
- toggleClass(row, "disabledStyle");
-
- var rule = Firebug.getRepObject(target);
-
- if (hasClass(target, "cssPropName"))
- {
- if (value && previousValue != value) // name of property has changed.
- {
- var propValue = getChildByClass(row, "cssPropValue")[textContent];
- var parsedValue = parsePriority(propValue);
-
- if (propValue && propValue != "undefined") {
- if (FBTrace.DBG_CSS)
- FBTrace.sysout("CSSEditor.saveEdit : "+previousValue+"->"+value+" = "+propValue+"\n");
- if (previousValue)
- Firebug.CSSModule.removeProperty(rule, previousValue);
- Firebug.CSSModule.setProperty(rule, value, parsedValue.value, parsedValue.priority);
- }
- }
- else if (!value) // name of the property has been deleted, so remove the property.
- Firebug.CSSModule.removeProperty(rule, previousValue);
- }
- else if (getAncestorByClass(target, "cssPropValue"))
- {
- var propName = getChildByClass(row, "cssPropName")[textContent];
- var propValue = getChildByClass(row, "cssPropValue")[textContent];
-
- if (FBTrace.DBG_CSS)
- {
- FBTrace.sysout("CSSEditor.saveEdit propName=propValue: "+propName +" = "+propValue+"\n");
- // FBTrace.sysout("CSSEditor.saveEdit BEFORE style:",style);
- }
-
- if (value && value != "null")
- {
- var parsedValue = parsePriority(value);
- Firebug.CSSModule.setProperty(rule, propName, parsedValue.value, parsedValue.priority);
- }
- else if (previousValue && previousValue != "null")
- Firebug.CSSModule.removeProperty(rule, propName);
- }
-
- this.panel.markChange(this.panel.name == "stylesheet");
- },
-
- advanceToNext: function(target, charCode)
- {
- if (charCode == 58 /*":"*/ && hasClass(target, "cssPropName"))
- return true;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- getAutoCompleteRange: function(value, offset)
- {
- if (hasClass(this.target, "cssPropName"))
- return {start: 0, end: value.length-1};
- else
- return parseCSSValue(value, offset);
- },
-
- getAutoCompleteList: function(preExpr, expr, postExpr)
- {
- if (hasClass(this.target, "cssPropName"))
- {
- return getCSSPropertyNames();
- }
- else
- {
- var row = getAncestorByClass(this.target, "cssProp");
- var propName = getChildByClass(row, "cssPropName")[textContent];
- return getCSSKeywordsByProperty(propName);
- }
- }
-});
-
-//************************************************************************************************
-//CSSRuleEditor
-
-function CSSRuleEditor(doc)
-{
- this.initializeInline(doc);
- this.completeAsYouType = false;
-}
-CSSRuleEditor.uniquifier = 0;
-CSSRuleEditor.prototype = domplate(Firebug.InlineEditor.prototype,
-{
- insertNewRow: function(target, insertWhere)
- {
- var emptyRule = {
- selector: "",
- id: "",
- props: [],
- isSelectorEditable: true
- };
-
- if (insertWhere == "before")
- return CSSStyleRuleTag.tag.insertBefore({rule: emptyRule}, target);
- else
- return CSSStyleRuleTag.tag.insertAfter({rule: emptyRule}, target);
- },
-
- saveEdit: function(target, value, previousValue)
- {
- if (FBTrace.DBG_CSS)
- FBTrace.sysout("CSSRuleEditor.saveEdit: '" + value + "' '" + previousValue + "'", target);
-
- target.innerHTML = escapeForCss(value);
-
- if (value === previousValue) return;
-
- var row = getAncestorByClass(target, "cssRule");
- var styleSheet = this.panel.location;
- styleSheet = styleSheet.editStyleSheet ? styleSheet.editStyleSheet.sheet : styleSheet;
-
- var cssRules = styleSheet.cssRules;
- var rule = Firebug.getRepObject(target), oldRule = rule;
- var ruleIndex = cssRules.length;
- if (rule || Firebug.getRepObject(row.nextSibling))
- {
- var searchRule = rule || Firebug.getRepObject(row.nextSibling);
- for (ruleIndex=0; ruleIndex<cssRules.length && searchRule!=cssRules[ruleIndex]; ruleIndex++) {}
- }
-
- // Delete in all cases except for new add
- // We want to do this before the insert to ease change tracking
- if (oldRule)
- {
- Firebug.CSSModule.deleteRule(styleSheet, ruleIndex);
- }
-
- // Firefox does not follow the spec for the update selector text case.
- // When attempting to update the value, firefox will silently fail.
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=37468 for the quite
- // old discussion of this bug.
- // As a result we need to recreate the style every time the selector
- // changes.
- if (value)
- {
- var cssText = [ value, "{" ];
- var props = row.getElementsByClassName("cssProp");
- for (var i = 0; i < props.length; i++) {
- var propEl = props[i];
- if (!hasClass(propEl, "disabledStyle")) {
- cssText.push(getChildByClass(propEl, "cssPropName")[textContent]);
- cssText.push(":");
- cssText.push(getChildByClass(propEl, "cssPropValue")[textContent]);
- cssText.push(";");
- }
- }
- cssText.push("}");
- cssText = cssText.join("");
-
- try
- {
- var insertLoc = Firebug.CSSModule.insertRule(styleSheet, cssText, ruleIndex);
- rule = cssRules[insertLoc];
- ruleIndex++;
- }
- catch (err)
- {
- if (FBTrace.DBG_CSS || FBTrace.DBG_ERRORS)
- FBTrace.sysout("CSS Insert Error: "+err, err);
-
- target.innerHTML = escapeForCss(previousValue);
- row.repObject = undefined;
- return;
- }
- } else {
- rule = undefined;
- }
-
- // Update the rep object
- row.repObject = rule;
- if (!oldRule)
- {
- // Who knows what the domutils will return for rule line
- // for a recently created rule. To be safe we just generate
- // a unique value as this is only used as an internal key.
- var ruleId = "new/"+value+"/"+(++CSSRuleEditor.uniquifier);
- row.setAttribute("ruleId", ruleId);
- }
-
- this.panel.markChange(this.panel.name == "stylesheet");
- }
-});
-
-// ************************************************************************************************
-// StyleSheetEditor
-
-function StyleSheetEditor(doc)
-{
- this.box = this.tag.replace({}, doc, this);
- this.input = this.box.firstChild;
-}
-
-StyleSheetEditor.prototype = domplate(Firebug.BaseEditor,
-{
- multiLine: true,
-
- tag: DIV(
- TEXTAREA({"class": "styleSheetEditor fullPanelEditor", oninput: "$onInput"})
- ),
-
- getValue: function()
- {
- return this.input.value;
- },
-
- setValue: function(value)
- {
- return this.input.value = value;
- },
-
- show: function(target, panel, value, textSize, targetSize)
- {
- this.target = target;
- this.panel = panel;
-
- this.panel.panelNode.appendChild(this.box);
-
- this.input.value = value;
- this.input.focus();
-
- var command = Firebug.chrome.$("cmd_toggleCSSEditing");
- command.setAttribute("checked", true);
- },
-
- hide: function()
- {
- var command = Firebug.chrome.$("cmd_toggleCSSEditing");
- command.setAttribute("checked", false);
-
- if (this.box.parentNode == this.panel.panelNode)
- this.panel.panelNode.removeChild(this.box);
-
- delete this.target;
- delete this.panel;
- delete this.styleSheet;
- },
-
- saveEdit: function(target, value, previousValue)
- {
- Firebug.CSSModule.freeEdit(this.styleSheet, value);
- },
-
- endEditing: function()
- {
- this.panel.refresh();
- return true;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- onInput: function()
- {
- Firebug.Editor.update();
- },
-
- scrollToLine: function(line, offset)
- {
- this.startMeasuring(this.input);
- var lineHeight = this.measureText().height;
- this.stopMeasuring();
-
- this.input.scrollTop = (line * lineHeight) + offset;
- }
-});
-
-// ************************************************************************************************
-// Local Helpers
-
-var rgbToHex = function rgbToHex(value)
-{
- return value.replace(/\brgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)/gi, rgbToHexReplacer);
-};
-
-var rgbToHexReplacer = function(_, r, g, b) {
- return '#' + ((1 << 24) + (r << 16) + (g << 8) + (b << 0)).toString(16).substr(-6).toUpperCase();
-};
-
-var stripUnits = function stripUnits(value)
-{
- // remove units from '0px', '0em' etc. leave non-zero units in-tact.
- return value.replace(/(url\(.*?\)|[^0]\S*\s*)|0(%|em|ex|px|in|cm|mm|pt|pc)(\s|$)/gi, stripUnitsReplacer);
-};
-
-var stripUnitsReplacer = function(_, skip, remove, whitespace) {
- return skip || ('0' + whitespace);
-};
-
-function parsePriority(value)
-{
- var rePriority = /(.*?)\s*(!important)?$/;
- var m = rePriority.exec(value);
- var propValue = m ? m[1] : "";
- var priority = m && m[2] ? "important" : "";
- return {value: propValue, priority: priority};
-}
-
-function parseURLValue(value)
-{
- var m = reURL.exec(value);
- return m ? m[1] : "";
-}
-
-function parseRepeatValue(value)
-{
- var m = reRepeat.exec(value);
- return m ? m[0] : "";
-}
-
-function parseCSSValue(value, offset)
-{
- var start = 0;
- var m;
- while (1)
- {
- m = reSplitCSS.exec(value);
- if (m && m.index+m[0].length < offset)
- {
- value = value.substr(m.index+m[0].length);
- start += m.index+m[0].length;
- offset -= m.index+m[0].length;
- }
- else
- break;
- }
-
- if (m)
- {
- var type;
- if (m[1])
- type = "url";
- else if (m[2] || m[3])
- type = "rgb";
- else if (m[4])
- type = "int";
-
- return {value: m[0], start: start+m.index, end: start+m.index+(m[0].length-1), type: type};
- }
-}
-
-function findPropByName(props, name)
-{
- for (var i = 0; i < props.length; ++i)
- {
- if (props[i].name == name)
- return i;
- }
-}
-
-function sortProperties(props)
-{
- props.sort(function(a, b)
- {
- return a.name > b.name ? 1 : -1;
- });
-}
-
-function getTopmostRuleLine(panelNode)
-{
- for (var child = panelNode.firstChild; child; child = child.nextSibling)
- {
- if (child.offsetTop+child.offsetHeight > panelNode.scrollTop)
- {
- var rule = child.repObject;
- if (rule)
- return {
- line: domUtils.getRuleLine(rule),
- offset: panelNode.scrollTop-child.offsetTop
- };
- }
- }
- return 0;
-}
-
-function getStyleSheetCSS(sheet, context)
-{
- if (sheet.ownerNode instanceof HTMLStyleElement)
- return sheet.ownerNode.innerHTML;
- else
- return context.sourceCache.load(sheet.href).join("");
-}
-
-function getStyleSheetOwnerNode(sheet) {
- for (; sheet && !sheet.ownerNode; sheet = sheet.parentStyleSheet);
-
- return sheet.ownerNode;
-}
-
-function scrollSelectionIntoView(panel)
-{
- var selCon = getSelectionController(panel);
- selCon.scrollSelectionIntoView(
- nsISelectionController.SELECTION_NORMAL,
- nsISelectionController.SELECTION_FOCUS_REGION, true);
-}
-
-function getSelectionController(panel)
-{
- var browser = Firebug.chrome.getPanelBrowser(panel);
- return browser.docShell.QueryInterface(nsIInterfaceRequestor)
- .getInterface(nsISelectionDisplay)
- .QueryInterface(nsISelectionController);
-}
-
-// ************************************************************************************************
-
-Firebug.registerModule(Firebug.CSSModule);
-Firebug.registerPanel(Firebug.CSSStyleSheetPanel);
-Firebug.registerPanel(CSSElementPanel);
-Firebug.registerPanel(CSSComputedElementPanel);
-
-// ************************************************************************************************
-
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-// ************************************************************************************************
-// Script Module
-
-Firebug.Script = extend(Firebug.Module,
-{
- getPanel: function()
- {
- return Firebug.chrome ? Firebug.chrome.getPanel("Script") : null;
- },
-
- selectSourceCode: function(index)
- {
- this.getPanel().selectSourceCode(index);
- }
-});
-
-Firebug.registerModule(Firebug.Script);
-
-
-// ************************************************************************************************
-// Script Panel
-
-function ScriptPanel(){};
-
-ScriptPanel.prototype = extend(Firebug.Panel,
-{
- name: "Script",
- title: "Script",
-
- selectIndex: 0, // index of the current selectNode's option
- sourceIndex: -1, // index of the script node, based in doc.getElementsByTagName("script")
-
- options: {
- hasToolButtons: true
- },
-
- create: function()
- {
- Firebug.Panel.create.apply(this, arguments);
-
- this.onChangeSelect = bind(this.onChangeSelect, this);
-
- var doc = Firebug.browser.document;
- var scripts = doc.getElementsByTagName("script");
- var selectNode = this.selectNode = createElement("select");
-
- for(var i=0, script; script=scripts[i]; i++)
- {
- // Don't show Firebug Lite source code in the list of options
- if (Firebug.ignoreFirebugElements && script.getAttribute("firebugIgnore"))
- continue;
-
- var fileName = getFileName(script.src) || getFileName(doc.location.href);
- var option = createElement("option", {value:i});
-
- option.appendChild(Firebug.chrome.document.createTextNode(fileName));
- selectNode.appendChild(option);
- };
-
- this.toolButtonsNode.appendChild(selectNode);
- },
-
- initialize: function()
- {
- // we must render the code first, so the persistent state can be restore
- this.selectSourceCode(this.selectIndex);
-
- Firebug.Panel.initialize.apply(this, arguments);
-
- addEvent(this.selectNode, "change", this.onChangeSelect);
- },
-
- shutdown: function()
- {
- removeEvent(this.selectNode, "change", this.onChangeSelect);
-
- Firebug.Panel.shutdown.apply(this, arguments);
- },
-
- detach: function(oldChrome, newChrome)
- {
- Firebug.Panel.detach.apply(this, arguments);
-
- var oldPanel = oldChrome.getPanel("Script");
- var index = oldPanel.selectIndex;
-
- this.selectNode.selectedIndex = index;
- this.selectIndex = index;
- this.sourceIndex = -1;
- },
-
- onChangeSelect: function(event)
- {
- var select = this.selectNode;
-
- this.selectIndex = select.selectedIndex;
-
- var option = select.options[select.selectedIndex];
- if (!option)
- return;
-
- var selectedSourceIndex = parseInt(option.value);
-
- this.renderSourceCode(selectedSourceIndex);
- },
-
- selectSourceCode: function(index)
- {
- var select = this.selectNode;
- select.selectedIndex = index;
-
- var option = select.options[index];
- if (!option)
- return;
-
- var selectedSourceIndex = parseInt(option.value);
-
- this.renderSourceCode(selectedSourceIndex);
- },
-
- renderSourceCode: function(index)
- {
- if (this.sourceIndex != index)
- {
- var renderProcess = function renderProcess(src)
- {
- var html = [],
- hl = 0;
-
- src = isIE && !isExternal ?
- src+'\n' : // IE put an extra line when reading source of local resources
- '\n'+src;
-
- // find the number of lines of code
- src = src.replace(/\n\r|\r\n/g, "\n");
- var match = src.match(/[\n]/g);
- var lines=match ? match.length : 0;
-
- // render the full source code + line numbers html
- html[hl++] = '<div><div class="sourceBox" style="left:';
- html[hl++] = 35 + 7*(lines+'').length;
- html[hl++] = 'px;"><pre class="sourceCode">';
- html[hl++] = escapeHTML(src);
- html[hl++] = '</pre></div><div class="lineNo">';
-
- // render the line number divs
- for(var l=1, lines; l<=lines; l++)
- {
- html[hl++] = '<div line="';
- html[hl++] = l;
- html[hl++] = '">';
- html[hl++] = l;
- html[hl++] = '</div>';
- }
-
- html[hl++] = '</div></div>';
-
- updatePanel(html);
- };
-
- var updatePanel = function(html)
- {
- self.panelNode.innerHTML = html.join("");
-
- // IE needs this timeout, otherwise the panel won't scroll
- setTimeout(function(){
- self.synchronizeUI();
- },0);
- };
-
- var onFailure = function()
- {
- FirebugReps.Warning.tag.replace({object: "AccessRestricted"}, self.panelNode);
- };
-
- var self = this;
-
- var doc = Firebug.browser.document;
- var script = doc.getElementsByTagName("script")[index];
- var url = getScriptURL(script);
- var isExternal = url && url != doc.location.href;
-
- try
- {
- if (Firebug.disableResourceFetching)
- {
- renderProcess(Firebug.Lite.Proxy.fetchResourceDisabledMessage);
- }
- else if (isExternal)
- {
- Ajax.request({url: url, onSuccess: renderProcess, onFailure: onFailure});
- }
- else
- {
- var src = script.innerHTML;
- renderProcess(src);
- }
- }
- catch(e)
- {
- onFailure();
- }
-
- this.sourceIndex = index;
- }
- }
-});
-
-Firebug.registerPanel(ScriptPanel);
-
-
-// ************************************************************************************************
-
-
-var getScriptURL = function getScriptURL(script)
-{
- var reFile = /([^\/\?#]+)(#.+)?$/;
- var rePath = /^(.*\/)/;
- var reProtocol = /^\w+:\/\//;
- var path = null;
- var doc = Firebug.browser.document;
-
- var file = reFile.exec(script.src);
-
- if (file)
- {
- var fileName = file[1];
- var fileOptions = file[2];
-
- // absolute path
- if (reProtocol.test(script.src)) {
- path = rePath.exec(script.src)[1];
-
- }
- // relative path
- else
- {
- var r = rePath.exec(script.src);
- var src = r ? r[1] : script.src;
- var backDir = /^((?:\.\.\/)+)(.*)/.exec(src);
- var reLastDir = /^(.*\/)[^\/]+\/$/;
- path = rePath.exec(doc.location.href)[1];
-
- // "../some/path"
- if (backDir)
- {
- var j = backDir[1].length/3;
- var p;
- while (j-- > 0)
- path = reLastDir.exec(path)[1];
-
- path += backDir[2];
- }
-
- else if(src.indexOf("/") != -1)
- {
- // "./some/path"
- if(/^\.\/./.test(src))
- {
- path += src.substring(2);
- }
- // "/some/path"
- else if(/^\/./.test(src))
- {
- var domain = /^(\w+:\/\/[^\/]+)/.exec(path);
- path = domain[1] + src;
- }
- // "some/path"
- else
- {
- path += src;
- }
- }
- }
- }
-
- var m = path && path.match(/([^\/]+)\/$/) || null;
-
- if (path && m)
- {
- return path + fileName;
- }
-};
-
-var getFileName = function getFileName(path)
-{
- if (!path) return "";
-
- var match = path && path.match(/[^\/]+(\?.*)?(#.*)?$/);
-
- return match && match[0] || path;
-};
-
-
-// ************************************************************************************************
-}});
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var ElementCache = Firebug.Lite.Cache.Element;
-
-var insertSliceSize = 18;
-var insertInterval = 40;
-
-var ignoreVars =
-{
- "__firebug__": 1,
- "eval": 1,
-
- // We are forced to ignore Java-related variables, because
- // trying to access them causes browser freeze
- "java": 1,
- "sun": 1,
- "Packages": 1,
- "JavaArray": 1,
- "JavaMember": 1,
- "JavaObject": 1,
- "JavaClass": 1,
- "JavaPackage": 1,
- "_firebug": 1,
- "_FirebugConsole": 1,
- "_FirebugCommandLine": 1
-};
-
-if (Firebug.ignoreFirebugElements)
- ignoreVars[Firebug.Lite.Cache.ID] = 1;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var memberPanelRep =
- isIE6 ?
- {"class": "memberLabel $member.type\\Label", href: "javacript:void(0)"}
- :
- {"class": "memberLabel $member.type\\Label"};
-
-var RowTag =
- TR({"class": "memberRow $member.open $member.type\\Row", $hasChildren: "$member.hasChildren", role : 'presentation',
- level: "$member.level"},
- TD({"class": "memberLabelCell", style: "padding-left: $member.indent\\px", role : 'presentation'},
- A(memberPanelRep,
- SPAN({}, "$member.name")
- )
- ),
- TD({"class": "memberValueCell", role : 'presentation'},
- TAG("$member.tag", {object: "$member.value"})
- )
- );
-
-var WatchRowTag =
- TR({"class": "watchNewRow", level: 0},
- TD({"class": "watchEditCell", colspan: 2},
- DIV({"class": "watchEditBox a11yFocusNoTab", role: "button", 'tabindex' : '0',
- 'aria-label' : $STR('press enter to add new watch expression')},
- $STR("NewWatch")
- )
- )
- );
-
-var SizerRow =
- TR({role : 'presentation'},
- TD({width: "30%"}),
- TD({width: "70%"})
- );
-
-var domTableClass = isIElt8 ? "domTable domTableIE" : "domTable";
-var DirTablePlate = domplate(Firebug.Rep,
-{
- tag:
- TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0, onclick: "$onClick", role :"tree"},
- TBODY({role: 'presentation'},
- SizerRow,
- FOR("member", "$object|memberIterator", RowTag)
- )
- ),
-
- watchTag:
- TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0,
- _toggles: "$toggles", _domPanel: "$domPanel", onclick: "$onClick", role : 'tree'},
- TBODY({role : 'presentation'},
- SizerRow,
- WatchRowTag
- )
- ),
-
- tableTag:
- TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0,
- _toggles: "$toggles", _domPanel: "$domPanel", onclick: "$onClick", role : 'tree'},
- TBODY({role : 'presentation'},
- SizerRow
- )
- ),
-
- rowTag:
- FOR("member", "$members", RowTag),
-
- memberIterator: function(object, level)
- {
- return getMembers(object, level);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- onClick: function(event)
- {
- if (!isLeftClick(event))
- return;
-
- var target = event.target || event.srcElement;
-
- var row = getAncestorByClass(target, "memberRow");
- var label = getAncestorByClass(target, "memberLabel");
- if (label && hasClass(row, "hasChildren"))
- {
- var row = label.parentNode.parentNode;
- this.toggleRow(row);
- }
- else
- {
- var object = Firebug.getRepObject(target);
- if (typeof(object) == "function")
- {
- Firebug.chrome.select(object, "script");
- cancelEvent(event);
- }
- else if (event.detail == 2 && !object)
- {
- var panel = row.parentNode.parentNode.domPanel;
- if (panel)
- {
- var rowValue = panel.getRowPropertyValue(row);
- if (typeof(rowValue) == "boolean")
- panel.setPropertyValue(row, !rowValue);
- else
- panel.editProperty(row);
-
- cancelEvent(event);
- }
- }
- }
-
- return false;
- },
-
- toggleRow: function(row)
- {
- var level = parseInt(row.getAttribute("level"));
- var toggles = row.parentNode.parentNode.toggles;
-
- if (hasClass(row, "opened"))
- {
- removeClass(row, "opened");
-
- if (toggles)
- {
- var path = getPath(row);
-
- // Remove the path from the toggle tree
- for (var i = 0; i < path.length; ++i)
- {
- if (i == path.length-1)
- delete toggles[path[i]];
- else
- toggles = toggles[path[i]];
- }
- }
-
- var rowTag = this.rowTag;
- var tbody = row.parentNode;
-
- setTimeout(function()
- {
- for (var firstRow = row.nextSibling; firstRow; firstRow = row.nextSibling)
- {
- if (parseInt(firstRow.getAttribute("level")) <= level)
- break;
-
- tbody.removeChild(firstRow);
- }
- }, row.insertTimeout ? row.insertTimeout : 0);
- }
- else
- {
- setClass(row, "opened");
-
- if (toggles)
- {
- var path = getPath(row);
-
- // Mark the path in the toggle tree
- for (var i = 0; i < path.length; ++i)
- {
- var name = path[i];
- if (toggles.hasOwnProperty(name))
- toggles = toggles[name];
- else
- toggles = toggles[name] = {};
- }
- }
-
- var value = row.lastChild.firstChild.repObject;
- var members = getMembers(value, level+1);
-
- var rowTag = this.rowTag;
- var lastRow = row;
-
- var delay = 0;
- //var setSize = members.length;
- //var rowCount = 1;
- while (members.length)
- {
- with({slice: members.splice(0, insertSliceSize), isLast: !members.length})
- {
- setTimeout(function()
- {
- if (lastRow.parentNode)
- {
- var result = rowTag.insertRows({members: slice}, lastRow);
- lastRow = result[1];
- //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [null, result, rowCount, setSize]);
- //rowCount += insertSliceSize;
- }
- if (isLast)
- row.removeAttribute("insertTimeout");
- }, delay);
- }
-
- delay += insertInterval;
- }
-
- row.insertTimeout = delay;
- }
- }
-});
-
-
-
-// ************************************************************************************************
-
-Firebug.DOMBasePanel = function() {};
-
-Firebug.DOMBasePanel.prototype = extend(Firebug.Panel,
-{
- tag: DirTablePlate.tableTag,
-
- getRealObject: function(object)
- {
- // TODO: Move this to some global location
- // TODO: Unwrapping should be centralized rather than sprinkling it around ad hoc.
- // TODO: We might be able to make this check more authoritative with QueryInterface.
- if (!object) return object;
- if (object.wrappedJSObject) return object.wrappedJSObject;
- return object;
- },
-
- rebuild: function(update, scrollTop)
- {
- //dispatch([Firebug.A11yModel], 'onBeforeDomUpdateSelection', [this]);
- var members = getMembers(this.selection);
- expandMembers(members, this.toggles, 0, 0);
-
- this.showMembers(members, update, scrollTop);
-
- //TODO: xxxpedro statusbar
- if (!this.parentPanel)
- updateStatusBar(this);
- },
-
- showMembers: function(members, update, scrollTop)
- {
- // If we are still in the midst of inserting rows, cancel all pending
- // insertions here - this is a big speedup when stepping in the debugger
- if (this.timeouts)
- {
- for (var i = 0; i < this.timeouts.length; ++i)
- this.context.clearTimeout(this.timeouts[i]);
- delete this.timeouts;
- }
-
- if (!members.length)
- return this.showEmptyMembers();
-
- var panelNode = this.panelNode;
- var priorScrollTop = scrollTop == undefined ? panelNode.scrollTop : scrollTop;
-
- // If we are asked to "update" the current view, then build the new table
- // offscreen and swap it in when it's done
- var offscreen = update && panelNode.firstChild;
- var dest = offscreen ? panelNode.ownerDocument : panelNode;
-
- var table = this.tag.replace({domPanel: this, toggles: this.toggles}, dest);
- var tbody = table.lastChild;
- var rowTag = DirTablePlate.rowTag;
-
- // Insert the first slice immediately
- //var slice = members.splice(0, insertSliceSize);
- //var result = rowTag.insertRows({members: slice}, tbody.lastChild);
-
- //var setSize = members.length;
- //var rowCount = 1;
-
- var panel = this;
- var result;
-
- //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]);
- var timeouts = [];
-
- var delay = 0;
-
- // enable to measure rendering performance
- var renderStart = new Date().getTime();
- while (members.length)
- {
- with({slice: members.splice(0, insertSliceSize), isLast: !members.length})
- {
- timeouts.push(this.context.setTimeout(function()
- {
- // TODO: xxxpedro can this be a timing error related to the
- // "iteration number" approach insted of "duration time"?
- // avoid error in IE8
- if (!tbody.lastChild) return;
-
- result = rowTag.insertRows({members: slice}, tbody.lastChild);
-
- //rowCount += insertSliceSize;
- //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]);
-
- if ((panelNode.scrollHeight+panelNode.offsetHeight) >= priorScrollTop)
- panelNode.scrollTop = priorScrollTop;
-
-
- // enable to measure rendering performance
- //if (isLast) alert(new Date().getTime() - renderStart + "ms");
-
-
- }, delay));
-
- delay += insertInterval;
- }
- }
-
- if (offscreen)
- {
- timeouts.push(this.context.setTimeout(function()
- {
- if (panelNode.firstChild)
- panelNode.replaceChild(table, panelNode.firstChild);
- else
- panelNode.appendChild(table);
-
- // Scroll back to where we were before
- panelNode.scrollTop = priorScrollTop;
- }, delay));
- }
- else
- {
- timeouts.push(this.context.setTimeout(function()
- {
- panelNode.scrollTop = scrollTop == undefined ? 0 : scrollTop;
- }, delay));
- }
- this.timeouts = timeouts;
- },
-
- /*
- // new
- showMembers: function(members, update, scrollTop)
- {
- // If we are still in the midst of inserting rows, cancel all pending
- // insertions here - this is a big speedup when stepping in the debugger
- if (this.timeouts)
- {
- for (var i = 0; i < this.timeouts.length; ++i)
- this.context.clearTimeout(this.timeouts[i]);
- delete this.timeouts;
- }
-
- if (!members.length)
- return this.showEmptyMembers();
-
- var panelNode = this.panelNode;
- var priorScrollTop = scrollTop == undefined ? panelNode.scrollTop : scrollTop;
-
- // If we are asked to "update" the current view, then build the new table
- // offscreen and swap it in when it's done
- var offscreen = update && panelNode.firstChild;
- var dest = offscreen ? panelNode.ownerDocument : panelNode;
-
- var table = this.tag.replace({domPanel: this, toggles: this.toggles}, dest);
- var tbody = table.lastChild;
- var rowTag = DirTablePlate.rowTag;
-
- // Insert the first slice immediately
- //var slice = members.splice(0, insertSliceSize);
- //var result = rowTag.insertRows({members: slice}, tbody.lastChild);
-
- //var setSize = members.length;
- //var rowCount = 1;
-
- var panel = this;
- var result;
-
- //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]);
- var timeouts = [];
-
- var delay = 0;
- var _insertSliceSize = insertSliceSize;
- var _insertInterval = insertInterval;
-
- // enable to measure rendering performance
- var renderStart = new Date().getTime();
- var lastSkip = renderStart, now;
-
- while (members.length)
- {
- with({slice: members.splice(0, _insertSliceSize), isLast: !members.length})
- {
- var _tbody = tbody;
- var _rowTag = rowTag;
- var _panelNode = panelNode;
- var _priorScrollTop = priorScrollTop;
-
- timeouts.push(this.context.setTimeout(function()
- {
- // TODO: xxxpedro can this be a timing error related to the
- // "iteration number" approach insted of "duration time"?
- // avoid error in IE8
- if (!_tbody.lastChild) return;
-
- result = _rowTag.insertRows({members: slice}, _tbody.lastChild);
-
- //rowCount += _insertSliceSize;
- //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]);
-
- if ((_panelNode.scrollHeight + _panelNode.offsetHeight) >= _priorScrollTop)
- _panelNode.scrollTop = _priorScrollTop;
-
-
- // enable to measure rendering performance
- //alert("gap: " + (new Date().getTime() - lastSkip));
- //lastSkip = new Date().getTime();
-
- //if (isLast) alert("new: " + (new Date().getTime() - renderStart) + "ms");
-
- }, delay));
-
- delay += _insertInterval;
- }
- }
-
- if (offscreen)
- {
- timeouts.push(this.context.setTimeout(function()
- {
- if (panelNode.firstChild)
- panelNode.replaceChild(table, panelNode.firstChild);
- else
- panelNode.appendChild(table);
-
- // Scroll back to where we were before
- panelNode.scrollTop = priorScrollTop;
- }, delay));
- }
- else
- {
- timeouts.push(this.context.setTimeout(function()
- {
- panelNode.scrollTop = scrollTop == undefined ? 0 : scrollTop;
- }, delay));
- }
- this.timeouts = timeouts;
- },
- /**/
-
- showEmptyMembers: function()
- {
- FirebugReps.Warning.tag.replace({object: "NoMembersWarning"}, this.panelNode);
- },
-
- findPathObject: function(object)
- {
- var pathIndex = -1;
- for (var i = 0; i < this.objectPath.length; ++i)
- {
- // IE needs === instead of == or otherwise some objects will
- // be considered equal to different objects, returning the
- // wrong index of the objectPath array
- if (this.getPathObject(i) === object)
- return i;
- }
-
- return -1;
- },
-
- getPathObject: function(index)
- {
- var object = this.objectPath[index];
-
- if (object instanceof Property)
- return object.getObject();
- else
- return object;
- },
-
- getRowObject: function(row)
- {
- var object = getRowOwnerObject(row);
- return object ? object : this.selection;
- },
-
- getRowPropertyValue: function(row)
- {
- var object = this.getRowObject(row);
- object = this.getRealObject(object);
- if (object)
- {
- var propName = getRowName(row);
-
- if (object instanceof jsdIStackFrame)
- return Firebug.Debugger.evaluate(propName, this.context);
- else
- return object[propName];
- }
- },
- /*
- copyProperty: function(row)
- {
- var value = this.getRowPropertyValue(row);
- copyToClipboard(value);
- },
-
- editProperty: function(row, editValue)
- {
- if (hasClass(row, "watchNewRow"))
- {
- if (this.context.stopped)
- Firebug.Editor.startEditing(row, "");
- else if (Firebug.Console.isAlwaysEnabled()) // not stopped in debugger, need command line
- {
- if (Firebug.CommandLine.onCommandLineFocus())
- Firebug.Editor.startEditing(row, "");
- else
- row.innerHTML = $STR("warning.Command line blocked?");
- }
- else
- row.innerHTML = $STR("warning.Console must be enabled");
- }
- else if (hasClass(row, "watchRow"))
- Firebug.Editor.startEditing(row, getRowName(row));
- else
- {
- var object = this.getRowObject(row);
- this.context.thisValue = object;
-
- if (!editValue)
- {
- var propValue = this.getRowPropertyValue(row);
-
- var type = typeof(propValue);
- if (type == "undefined" || type == "number" || type == "boolean")
- editValue = propValue;
- else if (type == "string")
- editValue = "\"" + escapeJS(propValue) + "\"";
- else if (propValue == null)
- editValue = "null";
- else if (object instanceof Window || object instanceof jsdIStackFrame)
- editValue = getRowName(row);
- else
- editValue = "this." + getRowName(row);
- }
-
-
- Firebug.Editor.startEditing(row, editValue);
- }
- },
-
- deleteProperty: function(row)
- {
- if (hasClass(row, "watchRow"))
- this.deleteWatch(row);
- else
- {
- var object = getRowOwnerObject(row);
- if (!object)
- object = this.selection;
- object = this.getRealObject(object);
-
- if (object)
- {
- var name = getRowName(row);
- try
- {
- delete object[name];
- }
- catch (exc)
- {
- return;
- }
-
- this.rebuild(true);
- this.markChange();
- }
- }
- },
-
- setPropertyValue: function(row, value) // value must be string
- {
- if(FBTrace.DBG_DOM)
- {
- FBTrace.sysout("row: "+row);
- FBTrace.sysout("value: "+value+" type "+typeof(value), value);
- }
-
- var name = getRowName(row);
- if (name == "this")
- return;
-
- var object = this.getRowObject(row);
- object = this.getRealObject(object);
- if (object && !(object instanceof jsdIStackFrame))
- {
- // unwrappedJSObject.property = unwrappedJSObject
- Firebug.CommandLine.evaluate(value, this.context, object, this.context.getGlobalScope(),
- function success(result, context)
- {
- if (FBTrace.DBG_DOM)
- FBTrace.sysout("setPropertyValue evaluate success object["+name+"]="+result+" type "+typeof(result), result);
- object[name] = result;
- },
- function failed(exc, context)
- {
- try
- {
- if (FBTrace.DBG_DOM)
- FBTrace.sysout("setPropertyValue evaluate failed with exc:"+exc+" object["+name+"]="+value+" type "+typeof(value), exc);
- // If the value doesn't parse, then just store it as a string. Some users will
- // not realize they're supposed to enter a JavaScript expression and just type
- // literal text
- object[name] = String(value); // unwrappedJSobject.property = string
- }
- catch (exc)
- {
- return;
- }
- }
- );
- }
- else if (this.context.stopped)
- {
- try
- {
- Firebug.CommandLine.evaluate(name+"="+value, this.context);
- }
- catch (exc)
- {
- try
- {
- // See catch block above...
- object[name] = String(value); // unwrappedJSobject.property = string
- }
- catch (exc)
- {
- return;
- }
- }
- }
-
- this.rebuild(true);
- this.markChange();
- },
-
- highlightRow: function(row)
- {
- if (this.highlightedRow)
- cancelClassTimed(this.highlightedRow, "jumpHighlight", this.context);
-
- this.highlightedRow = row;
-
- if (row)
- setClassTimed(row, "jumpHighlight", this.context);
- },/**/
-
- onMouseMove: function(event)
- {
- var target = event.srcElement || event.target;
-
- var object = getAncestorByClass(target, "objectLink-element");
- object = object ? object.repObject : null;
-
- if(object && instanceOf(object, "Element") && object.nodeType == 1)
- {
- if(object != lastHighlightedObject)
- {
- Firebug.Inspector.drawBoxModel(object);
- object = lastHighlightedObject;
- }
- }
- else
- Firebug.Inspector.hideBoxModel();
-
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // extends Panel
-
- create: function()
- {
- // TODO: xxxpedro
- this.context = Firebug.browser;
-
- this.objectPath = [];
- this.propertyPath = [];
- this.viewPath = [];
- this.pathIndex = -1;
- this.toggles = {};
-
- Firebug.Panel.create.apply(this, arguments);
-
- this.panelNode.style.padding = "0 1px";
- },
-
- initialize: function(){
- Firebug.Panel.initialize.apply(this, arguments);
-
- addEvent(this.panelNode, "mousemove", this.onMouseMove);
- },
-
- shutdown: function()
- {
- removeEvent(this.panelNode, "mousemove", this.onMouseMove);
-
- Firebug.Panel.shutdown.apply(this, arguments);
- },
-
- /*
- destroy: function(state)
- {
- var view = this.viewPath[this.pathIndex];
- if (view && this.panelNode.scrollTop)
- view.scrollTop = this.panelNode.scrollTop;
-
- if (this.pathIndex)
- state.pathIndex = this.pathIndex;
- if (this.viewPath)
- state.viewPath = this.viewPath;
- if (this.propertyPath)
- state.propertyPath = this.propertyPath;
-
- if (this.propertyPath.length > 0 && !this.propertyPath[1])
- state.firstSelection = persistObject(this.getPathObject(1), this.context);
-
- Firebug.Panel.destroy.apply(this, arguments);
- },
- /**/
-
- ishow: function(state)
- {
- if (this.context.loaded && !this.selection)
- {
- if (!state)
- {
- this.select(null);
- return;
- }
- if (state.viewPath)
- this.viewPath = state.viewPath;
- if (state.propertyPath)
- this.propertyPath = state.propertyPath;
-
- var defaultObject = this.getDefaultSelection(this.context);
- var selectObject = defaultObject;
-
- if (state.firstSelection)
- {
- var restored = state.firstSelection(this.context);
- if (restored)
- {
- selectObject = restored;
- this.objectPath = [defaultObject, restored];
- }
- else
- this.objectPath = [defaultObject];
- }
- else
- this.objectPath = [defaultObject];
-
- if (this.propertyPath.length > 1)
- {
- for (var i = 1; i < this.propertyPath.length; ++i)
- {
- var name = this.propertyPath[i];
- if (!name)
- continue;
-
- var object = selectObject;
- try
- {
- selectObject = object[name];
- }
- catch (exc)
- {
- selectObject = null;
- }
-
- if (selectObject)
- {
- this.objectPath.push(new Property(object, name));
- }
- else
- {
- // If we can't access a property, just stop
- this.viewPath.splice(i);
- this.propertyPath.splice(i);
- this.objectPath.splice(i);
- selectObject = this.getPathObject(this.objectPath.length-1);
- break;
- }
- }
- }
-
- var selection = state.pathIndex <= this.objectPath.length-1
- ? this.getPathObject(state.pathIndex)
- : this.getPathObject(this.objectPath.length-1);
-
- this.select(selection);
- }
- },
- /*
- hide: function()
- {
- var view = this.viewPath[this.pathIndex];
- if (view && this.panelNode.scrollTop)
- view.scrollTop = this.panelNode.scrollTop;
- },
- /**/
-
- supportsObject: function(object)
- {
- if (object == null)
- return 1000;
-
- if (typeof(object) == "undefined")
- return 1000;
- else if (object instanceof SourceLink)
- return 0;
- else
- return 1; // just agree to support everything but not agressively.
- },
-
- refresh: function()
- {
- this.rebuild(true);
- },
-
- updateSelection: function(object)
- {
- var previousIndex = this.pathIndex;
- var previousView = previousIndex == -1 ? null : this.viewPath[previousIndex];
-
- var newPath = this.pathToAppend;
- delete this.pathToAppend;
-
- var pathIndex = this.findPathObject(object);
- if (newPath || pathIndex == -1)
- {
- this.toggles = {};
-
- if (newPath)
- {
- // Remove everything after the point where we are inserting, so we
- // essentially replace it with the new path
- if (previousView)
- {
- if (this.panelNode.scrollTop)
- previousView.scrollTop = this.panelNode.scrollTop;
-
- var start = previousIndex + 1,
- // Opera needs the length argument in splice(), otherwise
- // it will consider that only one element should be removed
- length = this.objectPath.length - start;
-
- this.objectPath.splice(start, length);
- this.propertyPath.splice(start, length);
- this.viewPath.splice(start, length);
- }
-
- var value = this.getPathObject(previousIndex);
- if (!value)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("dom.updateSelection no pathObject for "+previousIndex+"\n");
- return;
- }
-
- for (var i = 0, length = newPath.length; i < length; ++i)
- {
- var name = newPath[i];
- var object = value;
- try
- {
- value = value[name];
- }
- catch(exc)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("dom.updateSelection FAILS at path_i="+i+" for name:"+name+"\n");
- return;
- }
-
- ++this.pathIndex;
- this.objectPath.push(new Property(object, name));
- this.propertyPath.push(name);
- this.viewPath.push({toggles: this.toggles, scrollTop: 0});
- }
- }
- else
- {
- this.toggles = {};
-
- var win = Firebug.browser.window;
- //var win = this.context.getGlobalScope();
- if (object === win)
- {
- this.pathIndex = 0;
- this.objectPath = [win];
- this.propertyPath = [null];
- this.viewPath = [{toggles: this.toggles, scrollTop: 0}];
- }
- else
- {
- this.pathIndex = 1;
- this.objectPath = [win, object];
- this.propertyPath = [null, null];
- this.viewPath = [
- {toggles: {}, scrollTop: 0},
- {toggles: this.toggles, scrollTop: 0}
- ];
- }
- }
-
- this.panelNode.scrollTop = 0;
- this.rebuild();
- }
- else
- {
- this.pathIndex = pathIndex;
-
- var view = this.viewPath[pathIndex];
- this.toggles = view.toggles;
-
- // Persist the current scroll location
- if (previousView && this.panelNode.scrollTop)
- previousView.scrollTop = this.panelNode.scrollTop;
-
- this.rebuild(false, view.scrollTop);
- }
- },
-
- getObjectPath: function(object)
- {
- return this.objectPath;
- },
-
- getDefaultSelection: function()
- {
- return Firebug.browser.window;
- //return this.context.getGlobalScope();
- }/*,
-
- updateOption: function(name, value)
- {
- const optionMap = {showUserProps: 1, showUserFuncs: 1, showDOMProps: 1,
- showDOMFuncs: 1, showDOMConstants: 1};
- if ( optionMap.hasOwnProperty(name) )
- this.rebuild(true);
- },
-
- getOptionsMenuItems: function()
- {
- return [
- optionMenu("ShowUserProps", "showUserProps"),
- optionMenu("ShowUserFuncs", "showUserFuncs"),
- optionMenu("ShowDOMProps", "showDOMProps"),
- optionMenu("ShowDOMFuncs", "showDOMFuncs"),
- optionMenu("ShowDOMConstants", "showDOMConstants"),
- "-",
- {label: "Refresh", command: bindFixed(this.rebuild, this, true) }
- ];
- },
-
- getContextMenuItems: function(object, target)
- {
- var row = getAncestorByClass(target, "memberRow");
-
- var items = [];
-
- if (row)
- {
- var rowName = getRowName(row);
- var rowObject = this.getRowObject(row);
- var rowValue = this.getRowPropertyValue(row);
-
- var isWatch = hasClass(row, "watchRow");
- var isStackFrame = rowObject instanceof jsdIStackFrame;
-
- if (typeof(rowValue) == "string" || typeof(rowValue) == "number")
- {
- // Functions already have a copy item in their context menu
- items.push(
- "-",
- {label: "CopyValue",
- command: bindFixed(this.copyProperty, this, row) }
- );
- }
-
- items.push(
- "-",
- {label: isWatch ? "EditWatch" : (isStackFrame ? "EditVariable" : "EditProperty"),
- command: bindFixed(this.editProperty, this, row) }
- );
-
- if (isWatch || (!isStackFrame && !isDOMMember(rowObject, rowName)))
- {
- items.push(
- {label: isWatch ? "DeleteWatch" : "DeleteProperty",
- command: bindFixed(this.deleteProperty, this, row) }
- );
- }
- }
-
- items.push(
- "-",
- {label: "Refresh", command: bindFixed(this.rebuild, this, true) }
- );
-
- return items;
- },
-
- getEditor: function(target, value)
- {
- if (!this.editor)
- this.editor = new DOMEditor(this.document);
-
- return this.editor;
- }/**/
-});
-
-// ************************************************************************************************
-
-// TODO: xxxpedro statusbar
-var updateStatusBar = function(panel)
-{
- var path = panel.propertyPath;
- var index = panel.pathIndex;
-
- var r = [];
-
- for (var i=0, l=path.length; i<l; i++)
- {
- r.push(i==index ? '<a class="fbHover fbButton fbBtnSelected" ' : '<a class="fbHover fbButton" ');
- r.push('pathIndex=');
- r.push(i);
-
- if(isIE6)
- r.push(' href="javascript:void(0)"');
-
- r.push('>');
- r.push(i==0 ? "window" : path[i] || "Object");
- r.push('</a>');
-
- if(i < l-1)
- r.push('<span class="fbStatusSeparator">&gt;</span>');
- }
- panel.statusBarNode.innerHTML = r.join("");
-};
-
-
-var DOMMainPanel = Firebug.DOMPanel = function () {};
-
-Firebug.DOMPanel.DirTable = DirTablePlate;
-
-DOMMainPanel.prototype = extend(Firebug.DOMBasePanel.prototype,
-{
- onClickStatusBar: function(event)
- {
- var target = event.srcElement || event.target;
- var element = getAncestorByClass(target, "fbHover");
-
- if(element)
- {
- var pathIndex = element.getAttribute("pathIndex");
-
- if(pathIndex)
- {
- this.select(this.getPathObject(pathIndex));
- }
- }
- },
-
- selectRow: function(row, target)
- {
- if (!target)
- target = row.lastChild.firstChild;
-
- if (!target || !target.repObject)
- return;
-
- this.pathToAppend = getPath(row);
-
- // If the object is inside an array, look up its index
- var valueBox = row.lastChild.firstChild;
- if (hasClass(valueBox, "objectBox-array"))
- {
- var arrayIndex = FirebugReps.Arr.getItemIndex(target);
- this.pathToAppend.push(arrayIndex);
- }
-
- // Make sure we get a fresh status path for the object, since otherwise
- // it might find the object in the existing path and not refresh it
- //Firebug.chrome.clearStatusPath();
-
- this.select(target.repObject, true);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- onClick: function(event)
- {
- var target = event.srcElement || event.target;
- var repNode = Firebug.getRepNode(target);
- if (repNode)
- {
- var row = getAncestorByClass(target, "memberRow");
- if (row)
- {
- this.selectRow(row, repNode);
- cancelEvent(event);
- }
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // extends Panel
-
- name: "DOM",
- title: "DOM",
- searchable: true,
- statusSeparator: ">",
-
- options: {
- hasToolButtons: true,
- hasStatusBar: true
- },
-
- create: function()
- {
- Firebug.DOMBasePanel.prototype.create.apply(this, arguments);
-
- this.onClick = bind(this.onClick, this);
-
- //TODO: xxxpedro
- this.onClickStatusBar = bind(this.onClickStatusBar, this);
-
- this.panelNode.style.padding = "0 1px";
- },
-
- initialize: function(oldPanelNode)
- {
- //this.panelNode.addEventListener("click", this.onClick, false);
- //dispatch([Firebug.A11yModel], 'onInitializeNode', [this, 'console']);
-
- Firebug.DOMBasePanel.prototype.initialize.apply(this, arguments);
-
- addEvent(this.panelNode, "click", this.onClick);
-
- // TODO: xxxpedro dom
- this.ishow();
-
- //TODO: xxxpedro
- addEvent(this.statusBarNode, "click", this.onClickStatusBar);
- },
-
- shutdown: function()
- {
- //this.panelNode.removeEventListener("click", this.onClick, false);
- //dispatch([Firebug.A11yModel], 'onDestroyNode', [this, 'console']);
-
- removeEvent(this.panelNode, "click", this.onClick);
-
- Firebug.DOMBasePanel.prototype.shutdown.apply(this, arguments);
- }/*,
-
- search: function(text, reverse)
- {
- if (!text)
- {
- delete this.currentSearch;
- this.highlightRow(null);
- return false;
- }
-
- var row;
- if (this.currentSearch && text == this.currentSearch.text)
- row = this.currentSearch.findNext(true, undefined, reverse, Firebug.searchCaseSensitive);
- else
- {
- function findRow(node) { return getAncestorByClass(node, "memberRow"); }
- this.currentSearch = new TextSearch(this.panelNode, findRow);
- row = this.currentSearch.find(text, reverse, Firebug.searchCaseSensitive);
- }
-
- if (row)
- {
- var sel = this.document.defaultView.getSelection();
- sel.removeAllRanges();
- sel.addRange(this.currentSearch.range);
-
- scrollIntoCenterView(row, this.panelNode);
-
- this.highlightRow(row);
- dispatch([Firebug.A11yModel], 'onDomSearchMatchFound', [this, text, row]);
- return true;
- }
- else
- {
- dispatch([Firebug.A11yModel], 'onDomSearchMatchFound', [this, text, null]);
- return false;
- }
- }/**/
-});
-
-Firebug.registerPanel(DOMMainPanel);
-
-
-// ************************************************************************************************
-
-
-
-// ************************************************************************************************
-// Local Helpers
-
-var getMembers = function getMembers(object, level) // we expect object to be user-level object wrapped in security blanket
-{
- if (!level)
- level = 0;
-
- var ordinals = [], userProps = [], userClasses = [], userFuncs = [],
- domProps = [], domFuncs = [], domConstants = [];
-
- try
- {
- var domMembers = getDOMMembers(object);
- //var domMembers = {}; // TODO: xxxpedro
- //var domConstantMap = {}; // TODO: xxxpedro
-
- if (object.wrappedJSObject)
- var insecureObject = object.wrappedJSObject;
- else
- var insecureObject = object;
-
- // IE function prototype is not listed in (for..in)
- if (isIE && isFunction(object))
- addMember("user", userProps, "prototype", object.prototype, level);
-
- for (var name in insecureObject) // enumeration is safe
- {
- if (ignoreVars[name] == 1) // javascript.options.strict says ignoreVars is undefined.
- continue;
-
- var val;
- try
- {
- val = insecureObject[name]; // getter is safe
- }
- catch (exc)
- {
- // Sometimes we get exceptions trying to access certain members
- if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM)
- FBTrace.sysout("dom.getMembers cannot access "+name, exc);
- }
-
- var ordinal = parseInt(name);
- if (ordinal || ordinal == 0)
- {
- addMember("ordinal", ordinals, name, val, level);
- }
- else if (isFunction(val))
- {
- if (isClassFunction(val) && !(name in domMembers))
- addMember("userClass", userClasses, name, val, level);
- else if (name in domMembers)
- addMember("domFunction", domFuncs, name, val, level, domMembers[name]);
- else
- addMember("userFunction", userFuncs, name, val, level);
- }
- else
- {
- //TODO: xxxpedro
- /*
- var getterFunction = insecureObject.__lookupGetter__(name),
- setterFunction = insecureObject.__lookupSetter__(name),
- prefix = "";
-
- if(getterFunction && !setterFunction)
- prefix = "get ";
- /**/
-
- var prefix = "";
-
- if (name in domMembers && !(name in domConstantMap))
- addMember("dom", domProps, (prefix+name), val, level, domMembers[name]);
- else if (name in domConstantMap)
- addMember("dom", domConstants, (prefix+name), val, level);
- else
- addMember("user", userProps, (prefix+name), val, level);
- }
- }
- }
- catch (exc)
- {
- // Sometimes we get exceptions just from trying to iterate the members
- // of certain objects, like StorageList, but don't let that gum up the works
- throw exc;
- if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM)
- FBTrace.sysout("dom.getMembers FAILS: ", exc);
- //throw exc;
- }
-
- function sortName(a, b) { return a.name > b.name ? 1 : -1; }
- function sortOrder(a, b) { return a.order > b.order ? 1 : -1; }
-
- var members = [];
-
- members.push.apply(members, ordinals);
-
- Firebug.showUserProps = true; // TODO: xxxpedro
- Firebug.showUserFuncs = true; // TODO: xxxpedro
- Firebug.showDOMProps = true;
- Firebug.showDOMFuncs = true;
- Firebug.showDOMConstants = true;
-
- if (Firebug.showUserProps)
- {
- userProps.sort(sortName);
- members.push.apply(members, userProps);
- }
-
- if (Firebug.showUserFuncs)
- {
- userClasses.sort(sortName);
- members.push.apply(members, userClasses);
-
- userFuncs.sort(sortName);
- members.push.apply(members, userFuncs);
- }
-
- if (Firebug.showDOMProps)
- {
- domProps.sort(sortName);
- members.push.apply(members, domProps);
- }
-
- if (Firebug.showDOMFuncs)
- {
- domFuncs.sort(sortName);
- members.push.apply(members, domFuncs);
- }
-
- if (Firebug.showDOMConstants)
- members.push.apply(members, domConstants);
-
- return members;
-};
-
-function expandMembers(members, toggles, offset, level) // recursion starts with offset=0, level=0
-{
- var expanded = 0;
- for (var i = offset; i < members.length; ++i)
- {
- var member = members[i];
- if (member.level > level)
- break;
-
- if ( toggles.hasOwnProperty(member.name) )
- {
- member.open = "opened"; // member.level <= level && member.name in toggles.
-
- var newMembers = getMembers(member.value, level+1); // sets newMembers.level to level+1
-
- var args = [i+1, 0];
- args.push.apply(args, newMembers);
- members.splice.apply(members, args);
-
- /*
- if (FBTrace.DBG_DOM)
- {
- FBTrace.sysout("expandMembers member.name", member.name);
- FBTrace.sysout("expandMembers toggles", toggles);
- FBTrace.sysout("expandMembers toggles[member.name]", toggles[member.name]);
- FBTrace.sysout("dom.expandedMembers level: "+level+" member", member);
- }
- /**/
-
- expanded += newMembers.length;
- i += newMembers.length + expandMembers(members, toggles[member.name], i+1, level+1);
- }
- }
-
- return expanded;
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-
-function isClassFunction(fn)
-{
- try
- {
- for (var name in fn.prototype)
- return true;
- } catch (exc) {}
- return false;
-}
-
-// FIXME: xxxpedro This function is already defined in Lib. If we keep this definition here, it
-// will crash IE9 when not running the IE Developer Tool with JavaScript Debugging enabled!!!
-// Check if this function is in fact defined in Firebug for Firefox. If so, we should remove
-// this from here. The only difference of this function is the IE hack to show up the prototype
-// of functions, but Firebug no longer shows the prototype for simple functions.
-//var hasProperties = function hasProperties(ob)
-//{
-// try
-// {
-// for (var name in ob)
-// return true;
-// } catch (exc) {}
-//
-// // IE function prototype is not listed in (for..in)
-// if (isFunction(ob)) return true;
-//
-// return false;
-//};
-
-FBL.ErrorCopy = function(message)
-{
- this.message = message;
-};
-
-var addMember = function addMember(type, props, name, value, level, order)
-{
- var rep = Firebug.getRep(value); // do this first in case a call to instanceof reveals contents
- var tag = rep.shortTag ? rep.shortTag : rep.tag;
-
- var ErrorCopy = function(){}; //TODO: xxxpedro
-
- var valueType = typeof(value);
- var hasChildren = hasProperties(value) && !(value instanceof ErrorCopy) &&
- (isFunction(value) || (valueType == "object" && value != null)
- || (valueType == "string" && value.length > Firebug.stringCropLength));
-
- props.push({
- name: name,
- value: value,
- type: type,
- rowClass: "memberRow-"+type,
- open: "",
- order: order,
- level: level,
- indent: level*16,
- hasChildren: hasChildren,
- tag: tag
- });
-};
-
-var getWatchRowIndex = function getWatchRowIndex(row)
-{
- var index = -1;
- for (; row && hasClass(row, "watchRow"); row = row.previousSibling)
- ++index;
- return index;
-};
-
-var getRowName = function getRowName(row)
-{
- var node = row.firstChild;
- return node.textContent ? node.textContent : node.innerText;
-};
-
-var getRowValue = function getRowValue(row)
-{
- return row.lastChild.firstChild.repObject;
-};
-
-var getRowOwnerObject = function getRowOwnerObject(row)
-{
- var parentRow = getParentRow(row);
- if (parentRow)
- return getRowValue(parentRow);
-};
-
-var getParentRow = function getParentRow(row)
-{
- var level = parseInt(row.getAttribute("level"))-1;
- for (row = row.previousSibling; row; row = row.previousSibling)
- {
- if (parseInt(row.getAttribute("level")) == level)
- return row;
- }
-};
-
-var getPath = function getPath(row)
-{
- var name = getRowName(row);
- var path = [name];
-
- var level = parseInt(row.getAttribute("level"))-1;
- for (row = row.previousSibling; row; row = row.previousSibling)
- {
- if (parseInt(row.getAttribute("level")) == level)
- {
- var name = getRowName(row);
- path.splice(0, 0, name);
-
- --level;
- }
- }
-
- return path;
-};
-
-// ************************************************************************************************
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-
-// ************************************************************************************************
-// DOM Module
-
-Firebug.DOM = extend(Firebug.Module,
-{
- getPanel: function()
- {
- return Firebug.chrome ? Firebug.chrome.getPanel("DOM") : null;
- }
-});
-
-Firebug.registerModule(Firebug.DOM);
-
-
-// ************************************************************************************************
-// DOM Panel
-
-var lastHighlightedObject;
-
-function DOMSidePanel(){};
-
-DOMSidePanel.prototype = extend(Firebug.DOMBasePanel.prototype,
-{
- selectRow: function(row, target)
- {
- if (!target)
- target = row.lastChild.firstChild;
-
- if (!target || !target.repObject)
- return;
-
- this.pathToAppend = getPath(row);
-
- // If the object is inside an array, look up its index
- var valueBox = row.lastChild.firstChild;
- if (hasClass(valueBox, "objectBox-array"))
- {
- var arrayIndex = FirebugReps.Arr.getItemIndex(target);
- this.pathToAppend.push(arrayIndex);
- }
-
- // Make sure we get a fresh status path for the object, since otherwise
- // it might find the object in the existing path and not refresh it
- //Firebug.chrome.clearStatusPath();
-
- var object = target.repObject;
-
- if (instanceOf(object, "Element"))
- {
- Firebug.HTML.selectTreeNode(ElementCache(object));
- }
- else
- {
- Firebug.chrome.selectPanel("DOM");
- Firebug.chrome.getPanel("DOM").select(object, true);
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- onClick: function(event)
- {
- /*
- var target = event.srcElement || event.target;
-
- var object = getAncestorByClass(target, "objectLink");
- object = object ? object.repObject : null;
-
- if(!object) return;
-
- if (instanceOf(object, "Element"))
- {
- Firebug.HTML.selectTreeNode(ElementCache(object));
- }
- else
- {
- Firebug.chrome.selectPanel("DOM");
- Firebug.chrome.getPanel("DOM").select(object, true);
- }
- /**/
-
-
- var target = event.srcElement || event.target;
- var repNode = Firebug.getRepNode(target);
- if (repNode)
- {
- var row = getAncestorByClass(target, "memberRow");
- if (row)
- {
- this.selectRow(row, repNode);
- cancelEvent(event);
- }
- }
- /**/
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // extends Panel
-
- name: "DOMSidePanel",
- parentPanel: "HTML",
- title: "DOM",
-
- options: {
- hasToolButtons: true
- },
-
- isInitialized: false,
-
- create: function()
- {
- Firebug.DOMBasePanel.prototype.create.apply(this, arguments);
-
- this.onClick = bind(this.onClick, this);
- },
-
- initialize: function(){
- Firebug.DOMBasePanel.prototype.initialize.apply(this, arguments);
-
- addEvent(this.panelNode, "click", this.onClick);
-
- // TODO: xxxpedro css2
- var selection = ElementCache.get(Firebug.context.persistedState.selectedHTMLElementId);
- if (selection)
- this.select(selection, true);
- },
-
- shutdown: function()
- {
- removeEvent(this.panelNode, "click", this.onClick);
-
- Firebug.DOMBasePanel.prototype.shutdown.apply(this, arguments);
- },
-
- reattach: function(oldChrome)
- {
- //this.isInitialized = oldChrome.getPanel("DOM").isInitialized;
- this.toggles = oldChrome.getPanel("DOMSidePanel").toggles;
- }
-
-});
-
-Firebug.registerPanel(DOMSidePanel);
-
-
-// ************************************************************************************************
-}});
-
-/* See license.txt for terms of usage */
-
-FBL.FBTrace = {};
-
-(function() {
-// ************************************************************************************************
-
-var traceOptions = {
- DBG_TIMESTAMP: 1,
- DBG_INITIALIZE: 1,
- DBG_CHROME: 1,
- DBG_ERRORS: 1,
- DBG_DISPATCH: 1,
- DBG_CSS: 1
-};
-
-this.module = null;
-
-this.initialize = function()
-{
- if (!this.messageQueue)
- this.messageQueue = [];
-
- for (var name in traceOptions)
- this[name] = traceOptions[name];
-};
-
-// ************************************************************************************************
-// FBTrace API
-
-this.sysout = function()
-{
- return this.logFormatted(arguments, "");
-};
-
-this.dumpProperties = function(title, object)
-{
- return this.logFormatted("dumpProperties() not supported.", "warning");
-};
-
-this.dumpStack = function()
-{
- return this.logFormatted("dumpStack() not supported.", "warning");
-};
-
-this.flush = function(module)
-{
- this.module = module;
-
- var queue = this.messageQueue;
- this.messageQueue = [];
-
- for (var i = 0; i < queue.length; ++i)
- this.writeMessage(queue[i][0], queue[i][1], queue[i][2]);
-};
-
-this.getPanel = function()
-{
- return this.module ? this.module.getPanel() : null;
-};
-
-//*************************************************************************************************
-
-this.logFormatted = function(objects, className)
-{
- var html = this.DBG_TIMESTAMP ? [getTimestamp(), " | "] : [];
- var length = objects.length;
-
- for (var i = 0; i < length; ++i)
- {
- appendText(" ", html);
-
- var object = objects[i];
-
- if (i == 0)
- {
- html.push("<b>");
- appendText(object, html);
- html.push("</b>");
- }
- else
- appendText(object, html);
- }
-
- return this.logRow(html, className);
-};
-
-this.logRow = function(message, className)
-{
- var panel = this.getPanel();
-
- if (panel && panel.panelNode)
- this.writeMessage(message, className);
- else
- {
- this.messageQueue.push([message, className]);
- }
-
- return this.LOG_COMMAND;
-};
-
-this.writeMessage = function(message, className)
-{
- var container = this.getPanel().containerNode;
- var isScrolledToBottom =
- container.scrollTop + container.offsetHeight >= container.scrollHeight;
-
- this.writeRow.call(this, message, className);
-
- if (isScrolledToBottom)
- container.scrollTop = container.scrollHeight - container.offsetHeight;
-};
-
-this.appendRow = function(row)
-{
- var container = this.getPanel().panelNode;
- container.appendChild(row);
-};
-
-this.writeRow = function(message, className)
-{
- var row = this.getPanel().panelNode.ownerDocument.createElement("div");
- row.className = "logRow" + (className ? " logRow-"+className : "");
- row.innerHTML = message.join("");
- this.appendRow(row);
-};
-
-//*************************************************************************************************
-
-function appendText(object, html)
-{
- html.push(escapeHTML(objectToString(object)));
-};
-
-function getTimestamp()
-{
- var now = new Date();
- var ms = "" + (now.getMilliseconds() / 1000).toFixed(3);
- ms = ms.substr(2);
-
- return now.toLocaleTimeString() + "." + ms;
-};
-
-//*************************************************************************************************
-
-var HTMLtoEntity =
-{
- "<": "&lt;",
- ">": "&gt;",
- "&": "&amp;",
- "'": "&#39;",
- '"': "&quot;"
-};
-
-function replaceChars(ch)
-{
- return HTMLtoEntity[ch];
-};
-
-function escapeHTML(value)
-{
- return (value+"").replace(/[<>&"']/g, replaceChars);
-};
-
-//*************************************************************************************************
-
-function objectToString(object)
-{
- try
- {
- return object+"";
- }
- catch (exc)
- {
- return null;
- }
-};
-
-// ************************************************************************************************
-}).apply(FBL.FBTrace);
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-// If application isn't in trace mode, the FBTrace panel won't be loaded
-if (!Env.Options.enableTrace) return;
-
-// ************************************************************************************************
-// FBTrace Module
-
-Firebug.Trace = extend(Firebug.Module,
-{
- getPanel: function()
- {
- return Firebug.chrome ? Firebug.chrome.getPanel("Trace") : null;
- },
-
- clear: function()
- {
- this.getPanel().panelNode.innerHTML = "";
- }
-});
-
-Firebug.registerModule(Firebug.Trace);
-
-
-// ************************************************************************************************
-// FBTrace Panel
-
-function TracePanel(){};
-
-TracePanel.prototype = extend(Firebug.Panel,
-{
- name: "Trace",
- title: "Trace",
-
- options: {
- hasToolButtons: true,
- innerHTMLSync: true
- },
-
- create: function(){
- Firebug.Panel.create.apply(this, arguments);
-
- this.clearButton = new Button({
- caption: "Clear",
- title: "Clear FBTrace logs",
- owner: Firebug.Trace,
- onClick: Firebug.Trace.clear
- });
- },
-
- initialize: function(){
- Firebug.Panel.initialize.apply(this, arguments);
-
- this.clearButton.initialize();
- },
-
- shutdown: function()
- {
- this.clearButton.shutdown();
-
- Firebug.Panel.shutdown.apply(this, arguments);
- }
-
-});
-
-Firebug.registerPanel(TracePanel);
-
-// ************************************************************************************************
-}});
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-// ************************************************************************************************
-// Globals
-
-var modules = [];
-var panelTypes = [];
-var panelTypeMap = {};
-
-var parentPanelMap = {};
-
-
-var registerModule = Firebug.registerModule;
-var registerPanel = Firebug.registerPanel;
-
-// ************************************************************************************************
-append(Firebug,
-{
- extend: function(fn)
- {
- if (Firebug.chrome && Firebug.chrome.addPanel)
- {
- var namespace = ns(fn);
- fn.call(namespace, FBL);
- }
- else
- {
- setTimeout(function(){Firebug.extend(fn);},100);
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Registration
-
- registerModule: function()
- {
- registerModule.apply(Firebug, arguments);
-
- modules.push.apply(modules, arguments);
-
- dispatch(modules, "initialize", []);
-
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.registerModule");
- },
-
- registerPanel: function()
- {
- registerPanel.apply(Firebug, arguments);
-
- panelTypes.push.apply(panelTypes, arguments);
-
- for (var i = 0, panelType; panelType = arguments[i]; ++i)
- {
- // TODO: xxxpedro investigate why Dev Panel throws an error
- if (panelType.prototype.name == "Dev") continue;
-
- panelTypeMap[panelType.prototype.name] = arguments[i];
-
- var parentPanelName = panelType.prototype.parentPanel;
- if (parentPanelName)
- {
- parentPanelMap[parentPanelName] = 1;
- }
- else
- {
- var panelName = panelType.prototype.name;
- var chrome = Firebug.chrome;
- chrome.addPanel(panelName);
-
- // tab click handler
- var onTabClick = function onTabClick()
- {
- chrome.selectPanel(panelName);
- return false;
- };
-
- chrome.addController([chrome.panelMap[panelName].tabNode, "mousedown", onTabClick]);
- }
- }
-
- if (FBTrace.DBG_INITIALIZE)
- for (var i = 0; i < arguments.length; ++i)
- FBTrace.sysout("Firebug.registerPanel", arguments[i].prototype.name);
- }
-
-});
-
-
-
-
-// ************************************************************************************************
-}});
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-FirebugChrome.Skin =
-{
- CSS: '.obscured{left:-999999px !important;}.collapsed{display:none;}[collapsed="true"]{display:none;}#fbCSS{padding:0 !important;}.cssPropDisable{float:left;display:block;width:2em;cursor:default;}.infoTip{z-index:2147483647;position:fixed;padding:2px 3px;border:1px solid #CBE087;background:LightYellow;font-family:Monaco,monospace;color:#000000;display:none;white-space:nowrap;pointer-events:none;}.infoTip[active="true"]{display:block;}.infoTipLoading{width:16px;height:16px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/loading_16.gif) no-repeat;}.infoTipImageBox{font-size:11px;min-width:100px;text-align:center;}.infoTipCaption{font-size:11px;font:Monaco,monospace;}.infoTipLoading > .infoTipImage,.infoTipLoading > .infoTipCaption{display:none;}h1.groupHeader{padding:2px 4px;margin:0 0 4px 0;border-top:1px solid #CCCCCC;border-bottom:1px solid #CCCCCC;background:#eee url(https://getfirebug.com/releases/lite/latest/skin/xp/group.gif) repeat-x;font-size:11px;font-weight:bold;_position:relative;}.inlineEditor,.fixedWidthEditor{z-index:2147483647;position:absolute;display:none;}.inlineEditor{margin-left:-6px;margin-top:-3px;}.textEditorInner,.fixedWidthEditor{margin:0 0 0 0 !important;padding:0;border:none !important;font:inherit;text-decoration:inherit;background-color:#FFFFFF;}.fixedWidthEditor{border-top:1px solid #888888 !important;border-bottom:1px solid #888888 !important;}.textEditorInner{position:relative;top:-7px;left:-5px;outline:none;resize:none;}.textEditorInner1{padding-left:11px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorBorders.png) repeat-y;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorBorders.gif) repeat-y;_overflow:hidden;}.textEditorInner2{position:relative;padding-right:2px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorBorders.png) repeat-y 100% 0;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorBorders.gif) repeat-y 100% 0;_position:fixed;}.textEditorTop1{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.png) no-repeat 100% 0;margin-left:11px;height:10px;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.gif) no-repeat 100% 0;_overflow:hidden;}.textEditorTop2{position:relative;left:-11px;width:11px;height:10px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.png) no-repeat;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.gif) no-repeat;}.textEditorBottom1{position:relative;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.png) no-repeat 100% 100%;margin-left:11px;height:12px;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.gif) no-repeat 100% 100%;}.textEditorBottom2{position:relative;left:-11px;width:11px;height:12px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.png) no-repeat 0 100%;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.gif) no-repeat 0 100%;}.panelNode-css{overflow-x:hidden;}.cssSheet > .insertBefore{height:1.5em;}.cssRule{position:relative;margin:0;padding:1em 0 0 6px;font-family:Monaco,monospace;color:#000000;}.cssRule:first-child{padding-top:6px;}.cssElementRuleContainer{position:relative;}.cssHead{padding-right:150px;}.cssProp{}.cssPropName{color:DarkGreen;}.cssPropValue{margin-left:8px;color:DarkBlue;}.cssOverridden span{text-decoration:line-through;}.cssInheritedRule{}.cssInheritLabel{margin-right:0.5em;font-weight:bold;}.cssRule .objectLink-sourceLink{top:0;}.cssProp.editGroup:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/disable.png) no-repeat 2px 1px;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/disable.gif) no-repeat 2px 1px;}.cssProp.editGroup.editing{background:none;}.cssProp.disabledStyle{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/disableHover.png) no-repeat 2px 1px;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/disableHover.gif) no-repeat 2px 1px;opacity:1;color:#CCCCCC;}.disabledStyle .cssPropName,.disabledStyle .cssPropValue{color:#CCCCCC;}.cssPropValue.editing + .cssSemi,.inlineExpander + .cssSemi{display:none;}.cssPropValue.editing{white-space:nowrap;}.stylePropName{font-weight:bold;padding:0 4px 4px 4px;width:50%;}.stylePropValue{width:50%;}.panelNode-net{overflow-x:hidden;}.netTable{width:100%;}.hideCategory-undefined .category-undefined,.hideCategory-html .category-html,.hideCategory-css .category-css,.hideCategory-js .category-js,.hideCategory-image .category-image,.hideCategory-xhr .category-xhr,.hideCategory-flash .category-flash,.hideCategory-txt .category-txt,.hideCategory-bin .category-bin{display:none;}.netHeadRow{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/group.gif) repeat-x #FFFFFF;}.netHeadCol{border-bottom:1px solid #CCCCCC;padding:2px 4px 2px 18px;font-weight:bold;}.netHeadLabel{white-space:nowrap;overflow:hidden;}.netHeaderRow{height:16px;}.netHeaderCell{cursor:pointer;-moz-user-select:none;border-bottom:1px solid #9C9C9C;padding:0 !important;font-weight:bold;background:#BBBBBB url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/tableHeader.gif) repeat-x;white-space:nowrap;}.netHeaderRow > .netHeaderCell:first-child > .netHeaderCellBox{padding:2px 14px 2px 18px;}.netHeaderCellBox{padding:2px 14px 2px 10px;border-left:1px solid #D9D9D9;border-right:1px solid #9C9C9C;}.netHeaderCell:hover:active{background:#959595 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/tableHeaderActive.gif) repeat-x;}.netHeaderSorted{background:#7D93B2 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/tableHeaderSorted.gif) repeat-x;}.netHeaderSorted > .netHeaderCellBox{border-right-color:#6B7C93;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/arrowDown.png) no-repeat right;}.netHeaderSorted.sortedAscending > .netHeaderCellBox{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/arrowUp.png);}.netHeaderSorted:hover:active{background:#536B90 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/tableHeaderSortedActive.gif) repeat-x;}.panelNode-net .netRowHeader{display:block;}.netRowHeader{cursor:pointer;display:none;height:15px;margin-right:0 !important;}.netRow .netRowHeader{background-position:5px 1px;}.netRow[breakpoint="true"] .netRowHeader{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/breakpoint.png);}.netRow[breakpoint="true"][disabledBreakpoint="true"] .netRowHeader{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/breakpointDisabled.png);}.netRow.category-xhr:hover .netRowHeader{background-color:#F6F6F6;}#netBreakpointBar{max-width:38px;}#netHrefCol > .netHeaderCellBox{border-left:0px;}.netRow .netRowHeader{width:3px;}.netInfoRow .netRowHeader{display:table-cell;}.netTable[hiddenCols~=netHrefCol] TD[id="netHrefCol"],.netTable[hiddenCols~=netHrefCol] TD.netHrefCol,.netTable[hiddenCols~=netStatusCol] TD[id="netStatusCol"],.netTable[hiddenCols~=netStatusCol] TD.netStatusCol,.netTable[hiddenCols~=netDomainCol] TD[id="netDomainCol"],.netTable[hiddenCols~=netDomainCol] TD.netDomainCol,.netTable[hiddenCols~=netSizeCol] TD[id="netSizeCol"],.netTable[hiddenCols~=netSizeCol] TD.netSizeCol,.netTable[hiddenCols~=netTimeCol] TD[id="netTimeCol"],.netTable[hiddenCols~=netTimeCol] TD.netTimeCol{display:none;}.netRow{background:LightYellow;}.netRow.loaded{background:#FFFFFF;}.netRow.loaded:hover{background:#EFEFEF;}.netCol{padding:0;vertical-align:top;border-bottom:1px solid #EFEFEF;white-space:nowrap;height:17px;}.netLabel{width:100%;}.netStatusCol{padding-left:10px;color:rgb(128,128,128);}.responseError > .netStatusCol{color:red;}.netDomainCol{padding-left:5px;}.netSizeCol{text-align:right;padding-right:10px;}.netHrefLabel{-moz-box-sizing:padding-box;overflow:hidden;z-index:10;position:absolute;padding-left:18px;padding-top:1px;max-width:15%;font-weight:bold;}.netFullHrefLabel{display:none;-moz-user-select:none;padding-right:10px;padding-bottom:3px;max-width:100%;background:#FFFFFF;z-index:200;}.netHrefCol:hover > .netFullHrefLabel{display:block;}.netRow.loaded:hover .netCol > .netFullHrefLabel{background-color:#EFEFEF;}.useA11y .a11yShowFullLabel{display:block;background-image:none !important;border:1px solid #CBE087;background-color:LightYellow;font-family:Monaco,monospace;color:#000000;font-size:10px;z-index:2147483647;}.netSizeLabel{padding-left:6px;}.netStatusLabel,.netDomainLabel,.netSizeLabel,.netBar{padding:1px 0 2px 0 !important;}.responseError{color:red;}.hasHeaders .netHrefLabel:hover{cursor:pointer;color:blue;text-decoration:underline;}.netLoadingIcon{position:absolute;border:0;margin-left:14px;width:16px;height:16px;background:transparent no-repeat 0 0;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/loading_16.gif);display:inline-block;}.loaded .netLoadingIcon{display:none;}.netBar,.netSummaryBar{position:relative;border-right:50px solid transparent;}.netResolvingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarResolving.gif) repeat-x;z-index:60;}.netConnectingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarConnecting.gif) repeat-x;z-index:50;}.netBlockingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarWaiting.gif) repeat-x;z-index:40;}.netSendingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarSending.gif) repeat-x;z-index:30;}.netWaitingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarResponded.gif) repeat-x;z-index:20;min-width:1px;}.netReceivingBar{position:absolute;left:0;top:0;bottom:0;background:#38D63B url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarLoading.gif) repeat-x;z-index:10;}.netWindowLoadBar,.netContentLoadBar{position:absolute;left:0;top:0;bottom:0;width:1px;background-color:red;z-index:70;opacity:0.5;display:none;margin-bottom:-1px;}.netContentLoadBar{background-color:Blue;}.netTimeLabel{-moz-box-sizing:padding-box;position:absolute;top:1px;left:100%;padding-left:6px;color:#444444;min-width:16px;}.loaded .netReceivingBar,.loaded.netReceivingBar{background:#B6B6B6 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarLoaded.gif) repeat-x;border-color:#B6B6B6;}.fromCache .netReceivingBar,.fromCache.netReceivingBar{background:#D6D6D6 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarCached.gif) repeat-x;border-color:#D6D6D6;}.netSummaryRow .netTimeLabel,.loaded .netTimeLabel{background:transparent;}.timeInfoTip{width:150px; height:40px}.timeInfoTipBar,.timeInfoTipEventBar{position:relative;display:block;margin:0;opacity:1;height:15px;width:4px;}.timeInfoTipEventBar{width:1px !important;}.timeInfoTipCell.startTime{padding-right:8px;}.timeInfoTipCell.elapsedTime{text-align:right;padding-right:8px;}.sizeInfoLabelCol{font-weight:bold;padding-right:10px;font-family:Lucida Grande,Tahoma,sans-serif;font-size:11px;}.sizeInfoSizeCol{font-weight:bold;}.sizeInfoDetailCol{color:gray;text-align:right;}.sizeInfoDescCol{font-style:italic;}.netSummaryRow .netReceivingBar{background:#BBBBBB;border:none;}.netSummaryLabel{color:#222222;}.netSummaryRow{background:#BBBBBB !important;font-weight:bold;}.netSummaryRow .netBar{border-right-color:#BBBBBB;}.netSummaryRow > .netCol{border-top:1px solid #999999;border-bottom:2px solid;-moz-border-bottom-colors:#EFEFEF #999999;padding-top:1px;padding-bottom:2px;}.netSummaryRow > .netHrefCol:hover{background:transparent !important;}.netCountLabel{padding-left:18px;}.netTotalSizeCol{text-align:right;padding-right:10px;}.netTotalTimeCol{text-align:right;}.netCacheSizeLabel{position:absolute;z-index:1000;left:0;top:0;}.netLimitRow{background:rgb(255,255,225) !important;font-weight:normal;color:black;font-weight:normal;}.netLimitLabel{padding-left:18px;}.netLimitRow > .netCol{border-bottom:2px solid;-moz-border-bottom-colors:#EFEFEF #999999;vertical-align:middle !important;padding-top:2px;padding-bottom:2px;}.netLimitButton{font-size:11px;padding-top:1px;padding-bottom:1px;}.netInfoCol{border-top:1px solid #EEEEEE;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/group.gif) repeat-x #FFFFFF;}.netInfoBody{margin:10px 0 4px 10px;}.netInfoTabs{position:relative;padding-left:17px;}.netInfoTab{position:relative;top:-3px;margin-top:10px;padding:4px 6px;border:1px solid transparent;border-bottom:none;_border:none;font-weight:bold;color:#565656;cursor:pointer;}.netInfoTabSelected{cursor:default !important;border:1px solid #D7D7D7 !important;border-bottom:none !important;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background-color:#FFFFFF;}.logRow-netInfo.error .netInfoTitle{color:red;}.logRow-netInfo.loading .netInfoResponseText{font-style:italic;color:#888888;}.loading .netInfoResponseHeadersTitle{display:none;}.netInfoResponseSizeLimit{font-family:Lucida Grande,Tahoma,sans-serif;padding-top:10px;font-size:11px;}.netInfoText{display:none;margin:0;border:1px solid #D7D7D7;border-right:none;padding:8px;background-color:#FFFFFF;font-family:Monaco,monospace;white-space:pre-wrap;}.netInfoTextSelected{display:block;}.netInfoParamName{padding-right:10px;font-family:Lucida Grande,Tahoma,sans-serif;font-weight:bold;vertical-align:top;text-align:right;white-space:nowrap;}.netInfoPostText .netInfoParamName{width:1px;}.netInfoParamValue{width:100%;}.netInfoHeadersText,.netInfoPostText,.netInfoPutText{padding-top:0;}.netInfoHeadersGroup,.netInfoPostParams,.netInfoPostSource{margin-bottom:4px;border-bottom:1px solid #D7D7D7;padding-top:8px;padding-bottom:2px;font-family:Lucida Grande,Tahoma,sans-serif;font-weight:bold;color:#565656;}.netInfoPostParamsTable,.netInfoPostPartsTable,.netInfoPostJSONTable,.netInfoPostXMLTable,.netInfoPostSourceTable{margin-bottom:10px;width:100%;}.netInfoPostContentType{color:#bdbdbd;padding-left:50px;font-weight:normal;}.netInfoHtmlPreview{border:0;width:100%;height:100%;}.netHeadersViewSource{color:#bdbdbd;margin-left:200px;font-weight:normal;}.netHeadersViewSource:hover{color:blue;cursor:pointer;}.netActivationRow,.netPageSeparatorRow{background:rgb(229,229,229) !important;font-weight:normal;color:black;}.netActivationLabel{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/infoIcon.png) no-repeat 3px 2px;padding-left:22px;}.netPageSeparatorRow{height:5px !important;}.netPageSeparatorLabel{padding-left:22px;height:5px !important;}.netPageRow{background-color:rgb(255,255,255);}.netPageRow:hover{background:#EFEFEF;}.netPageLabel{padding:1px 0 2px 18px !important;font-weight:bold;}.netActivationRow > .netCol{border-bottom:2px solid;-moz-border-bottom-colors:#EFEFEF #999999;padding-top:2px;padding-bottom:3px;}.twisty,.logRow-errorMessage > .hasTwisty > .errorTitle,.logRow-log > .objectBox-array.hasTwisty,.logRow-spy .spyHead .spyTitle,.logGroup > .logRow,.memberRow.hasChildren > .memberLabelCell > .memberLabel,.hasHeaders .netHrefLabel,.netPageRow > .netCol > .netPageTitle{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_open.gif);background-repeat:no-repeat;background-position:2px 2px;min-height:12px;}.logRow-errorMessage > .hasTwisty.opened > .errorTitle,.logRow-log > .objectBox-array.hasTwisty.opened,.logRow-spy.opened .spyHead .spyTitle,.logGroup.opened > .logRow,.memberRow.hasChildren.opened > .memberLabelCell > .memberLabel,.nodeBox.highlightOpen > .nodeLabel > .twisty,.nodeBox.open > .nodeLabel > .twisty,.netRow.opened > .netCol > .netHrefLabel,.netPageRow.opened > .netCol > .netPageTitle{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_close.gif);}.twisty{background-position:4px 4px;}* html .logRow-spy .spyHead .spyTitle,* html .logGroup .logGroupLabel,* html .hasChildren .memberLabelCell .memberLabel,* html .hasHeaders .netHrefLabel{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_open.gif);background-repeat:no-repeat;background-position:2px 2px;}* html .opened .spyHead .spyTitle,* html .opened .logGroupLabel,* html .opened .memberLabelCell .memberLabel{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_close.gif);background-repeat:no-repeat;background-position:2px 2px;}.panelNode-console{overflow-x:hidden;}.objectLink{text-decoration:none;}.objectLink:hover{cursor:pointer;text-decoration:underline;}.logRow{position:relative;margin:0;border-bottom:1px solid #D7D7D7;padding:2px 4px 1px 6px;background-color:#FFFFFF;overflow:hidden !important;}.useA11y .logRow:focus{border-bottom:1px solid #000000 !important;outline:none !important;background-color:#FFFFAD !important;}.useA11y .logRow:focus a.objectLink-sourceLink{background-color:#FFFFAD;}.useA11y .a11yFocus:focus,.useA11y .objectBox:focus{outline:2px solid #FF9933;background-color:#FFFFAD;}.useA11y .objectBox-null:focus,.useA11y .objectBox-undefined:focus{background-color:#888888 !important;}.useA11y .logGroup.opened > .logRow{border-bottom:1px solid #ffffff;}.logGroup{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/group.gif) repeat-x #FFFFFF;padding:0 !important;border:none !important;}.logGroupBody{display:none;margin-left:16px;border-left:1px solid #D7D7D7;border-top:1px solid #D7D7D7;background:#FFFFFF;}.logGroup > .logRow{background-color:transparent !important;font-weight:bold;}.logGroup.opened > .logRow{border-bottom:none;}.logGroup.opened > .logGroupBody{display:block;}.logRow-command > .objectBox-text{font-family:Monaco,monospace;color:#0000FF;white-space:pre-wrap;}.logRow-info,.logRow-warn,.logRow-error,.logRow-assert,.logRow-warningMessage,.logRow-errorMessage{padding-left:22px;background-repeat:no-repeat;background-position:4px 2px;}.logRow-assert,.logRow-warningMessage,.logRow-errorMessage{padding-top:0;padding-bottom:0;}.logRow-info,.logRow-info .objectLink-sourceLink{background-color:#FFFFFF;}.logRow-warn,.logRow-warningMessage,.logRow-warn .objectLink-sourceLink,.logRow-warningMessage .objectLink-sourceLink{background-color:cyan;}.logRow-error,.logRow-assert,.logRow-errorMessage,.logRow-error .objectLink-sourceLink,.logRow-errorMessage .objectLink-sourceLink{background-color:LightYellow;}.logRow-error,.logRow-assert,.logRow-errorMessage{color:#FF0000;}.logRow-info{}.logRow-warn,.logRow-warningMessage{}.logRow-error,.logRow-assert,.logRow-errorMessage{}.objectBox-string,.objectBox-text,.objectBox-number,.objectLink-element,.objectLink-textNode,.objectLink-function,.objectBox-stackTrace,.objectLink-profile{font-family:Monaco,monospace;}.objectBox-string,.objectBox-text,.objectLink-textNode{white-space:pre-wrap;}.objectBox-number,.objectLink-styleRule,.objectLink-element,.objectLink-textNode{color:#000088;}.objectBox-string{color:#FF0000;}.objectLink-function,.objectBox-stackTrace,.objectLink-profile{color:DarkGreen;}.objectBox-null,.objectBox-undefined{padding:0 2px;border:1px solid #666666;background-color:#888888;color:#FFFFFF;}.objectBox-exception{padding:0 2px 0 18px;color:red;}.objectLink-sourceLink{position:absolute;right:4px;top:2px;padding-left:8px;font-family:Lucida Grande,sans-serif;font-weight:bold;color:#0000FF;}.errorTitle{margin-top:0px;margin-bottom:1px;padding-top:2px;padding-bottom:2px;}.errorTrace{margin-left:17px;}.errorSourceBox{margin:2px 0;}.errorSource-none{display:none;}.errorSource-syntax > .errorBreak{visibility:hidden;}.errorSource{cursor:pointer;font-family:Monaco,monospace;color:DarkGreen;}.errorSource:hover{text-decoration:underline;}.errorBreak{cursor:pointer;display:none;margin:0 6px 0 0;width:13px;height:14px;vertical-align:bottom;opacity:0.1;}.hasBreakSwitch .errorBreak{display:inline;}.breakForError .errorBreak{opacity:1;}.assertDescription{margin:0;}.logRow-profile > .logRow > .objectBox-text{font-family:Lucida Grande,Tahoma,sans-serif;color:#000000;}.logRow-profile > .logRow > .objectBox-text:last-child{color:#555555;font-style:italic;}.logRow-profile.opened > .logRow{padding-bottom:4px;}.profilerRunning > .logRow{padding-left:22px !important;}.profileSizer{width:100%;overflow-x:auto;overflow-y:scroll;}.profileTable{border-bottom:1px solid #D7D7D7;padding:0 0 4px 0;}.profileTable tr[odd="1"]{background-color:#F5F5F5;vertical-align:middle;}.profileTable a{vertical-align:middle;}.profileTable td{padding:1px 4px 0 4px;}.headerCell{cursor:pointer;-moz-user-select:none;border-bottom:1px solid #9C9C9C;padding:0 !important;font-weight:bold;}.headerCellBox{padding:2px 4px;border-left:1px solid #D9D9D9;border-right:1px solid #9C9C9C;}.headerCell:hover:active{}.headerSorted{}.headerSorted > .headerCellBox{border-right-color:#6B7C93;}.headerSorted.sortedAscending > .headerCellBox{}.headerSorted:hover:active{}.linkCell{text-align:right;}.linkCell > .objectLink-sourceLink{position:static;}.logRow-stackTrace{padding-top:0;background:#f8f8f8;}.logRow-stackTrace > .objectBox-stackFrame{position:relative;padding-top:2px;}.objectLink-object{font-family:Lucida Grande,sans-serif;font-weight:bold;color:DarkGreen;white-space:pre-wrap;}.objectProp-object{color:DarkGreen;}.objectProps{color:#000;font-weight:normal;}.objectPropName{color:#777;}.objectProps .objectProp-string{color:#f55;}.objectProps .objectProp-number{color:#55a;}.objectProps .objectProp-object{color:#585;}.selectorTag,.selectorId,.selectorClass{font-family:Monaco,monospace;font-weight:normal;}.selectorTag{color:#0000FF;}.selectorId{color:DarkBlue;}.selectorClass{color:red;}.selectorHidden > .selectorTag{color:#5F82D9;}.selectorHidden > .selectorId{color:#888888;}.selectorHidden > .selectorClass{color:#D86060;}.selectorValue{font-family:Lucida Grande,sans-serif;font-style:italic;color:#555555;}.panelNode.searching .logRow{display:none;}.logRow.matched{display:block !important;}.logRow.matching{position:absolute;left:-1000px;top:-1000px;max-width:0;max-height:0;overflow:hidden;}.objectLeftBrace,.objectRightBrace,.objectEqual,.objectComma,.arrayLeftBracket,.arrayRightBracket,.arrayComma{font-family:Monaco,monospace;}.objectLeftBrace,.objectRightBrace,.arrayLeftBracket,.arrayRightBracket{font-weight:bold;}.objectLeftBrace,.arrayLeftBracket{margin-right:4px;}.objectRightBrace,.arrayRightBracket{margin-left:4px;}.logRow-dir{padding:0;}.logRow-errorMessage .hasTwisty .errorTitle,.logRow-spy .spyHead .spyTitle,.logGroup .logRow{cursor:pointer;padding-left:18px;background-repeat:no-repeat;background-position:3px 3px;}.logRow-errorMessage > .hasTwisty > .errorTitle{background-position:2px 3px;}.logRow-errorMessage > .hasTwisty > .errorTitle:hover,.logRow-spy .spyHead .spyTitle:hover,.logGroup > .logRow:hover{text-decoration:underline;}.logRow-spy{padding:0 !important;}.logRow-spy,.logRow-spy .objectLink-sourceLink{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/group.gif) repeat-x #FFFFFF;padding-right:4px;right:0;}.logRow-spy.opened{padding-bottom:4px;border-bottom:none;}.spyTitle{color:#000000;font-weight:bold;-moz-box-sizing:padding-box;overflow:hidden;z-index:100;padding-left:18px;}.spyCol{padding:0;white-space:nowrap;height:16px;}.spyTitleCol:hover > .objectLink-sourceLink,.spyTitleCol:hover > .spyTime,.spyTitleCol:hover > .spyStatus,.spyTitleCol:hover > .spyTitle{display:none;}.spyFullTitle{display:none;-moz-user-select:none;max-width:100%;background-color:Transparent;}.spyTitleCol:hover > .spyFullTitle{display:block;}.spyStatus{padding-left:10px;color:rgb(128,128,128);}.spyTime{margin-left:4px;margin-right:4px;color:rgb(128,128,128);}.spyIcon{margin-right:4px;margin-left:4px;width:16px;height:16px;vertical-align:middle;background:transparent no-repeat 0 0;display:none;}.loading .spyHead .spyRow .spyIcon{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/loading_16.gif);display:block;}.logRow-spy.loaded:not(.error) .spyHead .spyRow .spyIcon{width:0;margin:0;}.logRow-spy.error .spyHead .spyRow .spyIcon{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon-sm.png);display:block;background-position:2px 2px;}.logRow-spy .spyHead .netInfoBody{display:none;}.logRow-spy.opened .spyHead .netInfoBody{margin-top:10px;display:block;}.logRow-spy.error .spyTitle,.logRow-spy.error .spyStatus,.logRow-spy.error .spyTime{color:red;}.logRow-spy.loading .spyResponseText{font-style:italic;color:#888888;}.caption{font-family:Lucida Grande,Tahoma,sans-serif;font-weight:bold;color:#444444;}.warning{padding:10px;font-family:Lucida Grande,Tahoma,sans-serif;font-weight:bold;color:#888888;}.panelNode-dom{overflow-x:hidden !important;}.domTable{font-size:1em;width:100%;table-layout:fixed;background:#fff;}.domTableIE{width:auto;}.memberLabelCell{padding:2px 0 2px 0;vertical-align:top;}.memberValueCell{padding:1px 0 1px 5px;display:block;overflow:hidden;}.memberLabel{display:block;cursor:default;-moz-user-select:none;overflow:hidden;padding-left:18px;background-color:#FFFFFF;text-decoration:none;}.memberRow.hasChildren .memberLabelCell .memberLabel:hover{cursor:pointer;color:blue;text-decoration:underline;}.userLabel{color:#000000;font-weight:bold;}.userClassLabel{color:#E90000;font-weight:bold;}.userFunctionLabel{color:#025E2A;font-weight:bold;}.domLabel{color:#000000;}.domFunctionLabel{color:#025E2A;}.ordinalLabel{color:SlateBlue;font-weight:bold;}.scopesRow{padding:2px 18px;background-color:LightYellow;border-bottom:5px solid #BEBEBE;color:#666666;}.scopesLabel{background-color:LightYellow;}.watchEditCell{padding:2px 18px;background-color:LightYellow;border-bottom:1px solid #BEBEBE;color:#666666;}.editor-watchNewRow,.editor-memberRow{font-family:Monaco,monospace !important;}.editor-memberRow{padding:1px 0 !important;}.editor-watchRow{padding-bottom:0 !important;}.watchRow > .memberLabelCell{font-family:Monaco,monospace;padding-top:1px;padding-bottom:1px;}.watchRow > .memberLabelCell > .memberLabel{background-color:transparent;}.watchRow > .memberValueCell{padding-top:2px;padding-bottom:2px;}.watchRow > .memberLabelCell,.watchRow > .memberValueCell{background-color:#F5F5F5;border-bottom:1px solid #BEBEBE;}.watchToolbox{z-index:2147483647;position:absolute;right:0;padding:1px 2px;}#fbConsole{overflow-x:hidden !important;}#fbCSS{font:1em Monaco,monospace;padding:0 7px;}#fbstylesheetButtons select,#fbScriptButtons select{font:11px Lucida Grande,Tahoma,sans-serif;margin-top:1px;padding-left:3px;background:#fafafa;border:1px inset #fff;width:220px;outline:none;}.Selector{margin-top:10px}.CSSItem{margin-left:4%}.CSSText{padding-left:20px;}.CSSProperty{color:#005500;}.CSSValue{padding-left:5px; color:#000088;}#fbHTMLStatusBar{display:inline;}.fbToolbarButtons{display:none;}.fbStatusSeparator{display:block;float:left;padding-top:4px;}#fbStatusBarBox{display:none;}#fbToolbarContent{display:block;position:absolute;_position:absolute;top:0;padding-top:4px;height:23px;clip:rect(0,2048px,27px,0);}.fbTabMenuTarget{display:none !important;float:left;width:10px;height:10px;margin-top:6px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuTarget.png);}.fbTabMenuTarget:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuTargetHover.png);}.fbShadow{float:left;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/shadowAlpha.png) no-repeat bottom right !important;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/shadow2.gif) no-repeat bottom right;margin:10px 0 0 10px !important;margin:10px 0 0 5px;}.fbShadowContent{display:block;position:relative;background-color:#fff;border:1px solid #a9a9a9;top:-6px;left:-6px;}.fbMenu{display:none;position:absolute;font-size:11px;line-height:13px;z-index:2147483647;}.fbMenuContent{padding:2px;}.fbMenuSeparator{display:block;position:relative;padding:1px 18px 0;text-decoration:none;color:#000;cursor:default;background:#ACA899;margin:4px 0;}.fbMenuOption{display:block;position:relative;padding:2px 18px;text-decoration:none;color:#000;cursor:default;}.fbMenuOption:hover{color:#fff;background:#316AC5;}.fbMenuGroup{background:transparent url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuPin.png) no-repeat right 0;}.fbMenuGroup:hover{background:#316AC5 url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuPin.png) no-repeat right -17px;}.fbMenuGroupSelected{color:#fff;background:#316AC5 url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuPin.png) no-repeat right -17px;}.fbMenuChecked{background:transparent url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuCheckbox.png) no-repeat 4px 0;}.fbMenuChecked:hover{background:#316AC5 url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuCheckbox.png) no-repeat 4px -17px;}.fbMenuRadioSelected{background:transparent url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuRadio.png) no-repeat 4px 0;}.fbMenuRadioSelected:hover{background:#316AC5 url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuRadio.png) no-repeat 4px -17px;}.fbMenuShortcut{padding-right:85px;}.fbMenuShortcutKey{position:absolute;right:0;top:2px;width:77px;}#fbFirebugMenu{top:22px;left:0;}.fbMenuDisabled{color:#ACA899 !important;}#fbFirebugSettingsMenu{left:245px;top:99px;}#fbConsoleMenu{top:42px;left:48px;}.fbIconButton{display:block;}.fbIconButton{display:block;}.fbIconButton{display:block;float:left;height:20px;width:20px;color:#000;margin-right:2px;text-decoration:none;cursor:default;}.fbIconButton:hover{position:relative;top:-1px;left:-1px;margin-right:0;_margin-right:1px;color:#333;border:1px solid #fff;border-bottom:1px solid #bbb;border-right:1px solid #bbb;}.fbIconPressed{position:relative;margin-right:0;_margin-right:1px;top:0 !important;left:0 !important;height:19px;color:#333 !important;border:1px solid #bbb !important;border-bottom:1px solid #cfcfcf !important;border-right:1px solid #ddd !important;}#fbErrorPopup{position:absolute;right:0;bottom:0;height:19px;width:75px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 0;z-index:999;}#fbErrorPopupContent{position:absolute;right:0;top:1px;height:18px;width:75px;_width:74px;border-left:1px solid #aca899;}#fbErrorIndicator{position:absolute;top:2px;right:5px;}.fbBtnInspectActive{background:#aaa;color:#fff !important;}.fbBody{margin:0;padding:0;overflow:hidden;font-family:Lucida Grande,Tahoma,sans-serif;font-size:11px;background:#fff;}.clear{clear:both;}#fbMiniChrome{display:none;right:0;height:27px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 0;margin-left:1px;}#fbMiniContent{display:block;position:relative;left:-1px;right:0;top:1px;height:25px;border-left:1px solid #aca899;}#fbToolbarSearch{float:right;border:1px solid #ccc;margin:0 5px 0 0;background:#fff url(https://getfirebug.com/releases/lite/latest/skin/xp/search.png) no-repeat 4px 2px !important;background:#fff url(https://getfirebug.com/releases/lite/latest/skin/xp/search.gif) no-repeat 4px 2px;padding-left:20px;font-size:11px;}#fbToolbarErrors{float:right;margin:1px 4px 0 0;font-size:11px;}#fbLeftToolbarErrors{float:left;margin:7px 0px 0 5px;font-size:11px;}.fbErrors{padding-left:20px;height:14px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon.png) no-repeat !important;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon.gif) no-repeat;color:#f00;font-weight:bold;}#fbMiniErrors{display:inline;display:none;float:right;margin:5px 2px 0 5px;}#fbMiniIcon{float:right;margin:3px 4px 0;height:20px;width:20px;float:right;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) 0 -135px;cursor:pointer;}#fbChrome{font-family:Lucida Grande,Tahoma,sans-serif;font-size:11px;position:absolute;_position:static;top:0;left:0;height:100%;width:100%;border-collapse:collapse;border-spacing:0;background:#fff;overflow:hidden;}#fbChrome > tbody > tr > td{padding:0;}#fbTop{height:49px;}#fbToolbar{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 0;height:27px;font-size:11px;line-height:13px;}#fbPanelBarBox{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #dbd9c9 0 -27px;height:22px;}#fbContent{height:100%;vertical-align:top;}#fbBottom{height:18px;background:#fff;}#fbToolbarIcon{float:left;padding:0 5px 0;}#fbToolbarIcon a{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) 0 -135px;}#fbToolbarButtons{padding:0 2px 0 5px;}#fbToolbarButtons{padding:0 2px 0 5px;}.fbButton{text-decoration:none;display:block;float:left;color:#000;padding:4px 6px 4px 7px;cursor:default;}.fbButton:hover{color:#333;background:#f5f5ef url(https://getfirebug.com/releases/lite/latest/skin/xp/buttonBg.png);padding:3px 5px 3px 6px;border:1px solid #fff;border-bottom:1px solid #bbb;border-right:1px solid #bbb;}.fbBtnPressed{background:#e3e3db url(https://getfirebug.com/releases/lite/latest/skin/xp/buttonBgHover.png) !important;padding:3px 4px 2px 6px !important;margin:1px 0 0 1px !important;border:1px solid #ACA899 !important;border-color:#ACA899 #ECEBE3 #ECEBE3 #ACA899 !important;}#fbStatusBarBox{top:4px;cursor:default;}.fbToolbarSeparator{overflow:hidden;border:1px solid;border-color:transparent #fff transparent #777;_border-color:#eee #fff #eee #777;height:7px;margin:6px 3px;float:left;}.fbBtnSelected{font-weight:bold;}.fbStatusBar{color:#aca899;}.fbStatusBar a{text-decoration:none;color:black;}.fbStatusBar a:hover{color:blue;cursor:pointer;}#fbWindowButtons{position:absolute;white-space:nowrap;right:0;top:0;height:17px;width:48px;padding:5px;z-index:6;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 0;}#fbPanelBar1{width:1024px; z-index:8;left:0;white-space:nowrap;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #dbd9c9 0 -27px;position:absolute;left:4px;}#fbPanelBar2Box{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #dbd9c9 0 -27px;position:absolute;height:22px;width:300px; z-index:9;right:0;}#fbPanelBar2{position:absolute;width:290px; height:22px;padding-left:4px;}.fbPanel{display:none;}#fbPanelBox1,#fbPanelBox2{max-height:inherit;height:100%;font-size:1em;}#fbPanelBox2{background:#fff;}#fbPanelBox2{width:300px;background:#fff;}#fbPanel2{margin-left:6px;background:#fff;}#fbLargeCommandLine{display:none;position:absolute;z-index:9;top:27px;right:0;width:294px;height:201px;border-width:0;margin:0;padding:2px 0 0 2px;resize:none;outline:none;font-size:11px;overflow:auto;border-top:1px solid #B9B7AF;_right:-1px;_border-left:1px solid #fff;}#fbLargeCommandButtons{display:none;background:#ECE9D8;bottom:0;right:0;width:294px;height:21px;padding-top:1px;position:fixed;border-top:1px solid #ACA899;z-index:9;}#fbSmallCommandLineIcon{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/down.png) no-repeat;position:absolute;right:2px;bottom:3px;z-index:99;}#fbSmallCommandLineIcon:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/downHover.png) no-repeat;}.hide{overflow:hidden !important;position:fixed !important;display:none !important;visibility:hidden !important;}#fbCommand{height:18px;}#fbCommandBox{position:fixed;_position:absolute;width:100%;height:18px;bottom:0;overflow:hidden;z-index:9;background:#fff;border:0;border-top:1px solid #ccc;}#fbCommandIcon{position:absolute;color:#00f;top:2px;left:6px;display:inline;font:11px Monaco,monospace;z-index:10;}#fbCommandLine{position:absolute;width:100%;top:0;left:0;border:0;margin:0;padding:2px 0 2px 32px;font:11px Monaco,monospace;z-index:9;outline:none;}#fbLargeCommandLineIcon{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/up.png) no-repeat;position:absolute;right:1px;bottom:1px;z-index:10;}#fbLargeCommandLineIcon:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/upHover.png) no-repeat;}div.fbFitHeight{overflow:auto;position:relative;}.fbSmallButton{overflow:hidden;width:16px;height:16px;display:block;text-decoration:none;cursor:default;}#fbWindowButtons .fbSmallButton{float:right;}#fbWindow_btClose{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/min.png);}#fbWindow_btClose:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/minHover.png);}#fbWindow_btDetach{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/detach.png);}#fbWindow_btDetach:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/detachHover.png);}#fbWindow_btDeactivate{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/off.png);}#fbWindow_btDeactivate:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/offHover.png);}.fbTab{text-decoration:none;display:none;float:left;width:auto;float:left;cursor:default;font-family:Lucida Grande,Tahoma,sans-serif;font-size:11px;line-height:13px;font-weight:bold;height:22px;color:#565656;}.fbPanelBar span{float:left;}.fbPanelBar .fbTabL,.fbPanelBar .fbTabR{height:22px;width:8px;}.fbPanelBar .fbTabText{padding:4px 1px 0;}a.fbTab:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) 0 -73px;}a.fbTab:hover .fbTabL{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) -16px -96px;}a.fbTab:hover .fbTabR{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) -24px -96px;}.fbSelectedTab{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 -50px !important;color:#000;}.fbSelectedTab .fbTabL{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) 0 -96px !important;}.fbSelectedTab .fbTabR{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) -8px -96px !important;}#fbHSplitter{position:fixed;_position:absolute;left:0;top:0;width:100%;height:5px;overflow:hidden;cursor:n-resize !important;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/pixel_transparent.gif);z-index:9;}#fbHSplitter.fbOnMovingHSplitter{height:100%;z-index:100;}.fbVSplitter{background:#ece9d8;color:#000;border:1px solid #716f64;border-width:0 1px;border-left-color:#aca899;width:4px;cursor:e-resize;overflow:hidden;right:294px;text-decoration:none;z-index:10;position:absolute;height:100%;top:27px;}div.lineNo{font:1em/1.4545em Monaco,monospace;position:relative;float:left;top:0;left:0;margin:0 5px 0 0;padding:0 5px 0 10px;background:#eee;color:#888;border-right:1px solid #ccc;text-align:right;}.sourceBox{position:absolute;}.sourceCode{font:1em Monaco,monospace;overflow:hidden;white-space:pre;display:inline;}.nodeControl{margin-top:3px;margin-left:-14px;float:left;width:9px;height:9px;overflow:hidden;cursor:default;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_open.gif);_float:none;_display:inline;_position:absolute;}div.nodeMaximized{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_close.gif);}div.objectBox-element{padding:1px 3px;}.objectBox-selector{cursor:default;}.selectedElement{background:highlight;color:#fff !important;}.selectedElement span{color:#fff !important;}* html .selectedElement{position:relative;}@media screen and (-webkit-min-device-pixel-ratio:0){.selectedElement{background:#316AC5;color:#fff !important;}}.logRow *{font-size:1em;}.logRow{position:relative;border-bottom:1px solid #D7D7D7;padding:2px 4px 1px 6px;zbackground-color:#FFFFFF;}.logRow-command{font-family:Monaco,monospace;color:blue;}.objectBox-string,.objectBox-text,.objectBox-number,.objectBox-function,.objectLink-element,.objectLink-textNode,.objectLink-function,.objectBox-stackTrace,.objectLink-profile{font-family:Monaco,monospace;}.objectBox-null{padding:0 2px;border:1px solid #666666;background-color:#888888;color:#FFFFFF;}.objectBox-string{color:red;}.objectBox-number{color:#000088;}.objectBox-function{color:DarkGreen;}.objectBox-object{color:DarkGreen;font-weight:bold;font-family:Lucida Grande,sans-serif;}.objectBox-array{color:#000;}.logRow-info,.logRow-error,.logRow-warn{background:#fff no-repeat 2px 2px;padding-left:20px;padding-bottom:3px;}.logRow-info{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/infoIcon.png) !important;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/infoIcon.gif);}.logRow-warn{background-color:cyan;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/warningIcon.png) !important;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/warningIcon.gif);}.logRow-error{background-color:LightYellow;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon.png) !important;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon.gif);color:#f00;}.errorMessage{vertical-align:top;color:#f00;}.objectBox-sourceLink{position:absolute;right:4px;top:2px;padding-left:8px;font-family:Lucida Grande,sans-serif;font-weight:bold;color:#0000FF;}.selectorTag,.selectorId,.selectorClass{font-family:Monaco,monospace;font-weight:normal;}.selectorTag{color:#0000FF;}.selectorId{color:DarkBlue;}.selectorClass{color:red;}.objectBox-element{font-family:Monaco,monospace;color:#000088;}.nodeChildren{padding-left:26px;}.nodeTag{color:blue;cursor:pointer;}.nodeValue{color:#FF0000;font-weight:normal;}.nodeText,.nodeComment{margin:0 2px;vertical-align:top;}.nodeText{color:#333333;font-family:Monaco,monospace;}.nodeComment{color:DarkGreen;}.nodeHidden,.nodeHidden *{color:#888888;}.nodeHidden .nodeTag{color:#5F82D9;}.nodeHidden .nodeValue{color:#D86060;}.selectedElement .nodeHidden,.selectedElement .nodeHidden *{color:SkyBlue !important;}.log-object{}.property{position:relative;clear:both;height:15px;}.propertyNameCell{vertical-align:top;float:left;width:28%;position:absolute;left:0;z-index:0;}.propertyValueCell{float:right;width:68%;background:#fff;position:absolute;padding-left:5px;display:table-cell;right:0;z-index:1;}.propertyName{font-weight:bold;}.FirebugPopup{height:100% !important;}.FirebugPopup #fbWindowButtons{display:none !important;}.FirebugPopup #fbHSplitter{display:none !important;}',
- HTML: '<table id="fbChrome" cellpadding="0" cellspacing="0" border="0"><tbody><tr><td id="fbTop" colspan="2"><div id="fbWindowButtons"><a id="fbWindow_btDeactivate" class="fbSmallButton fbHover" title="Deactivate Firebug for this web page">&nbsp;</a><a id="fbWindow_btDetach" class="fbSmallButton fbHover" title="Open Firebug in popup window">&nbsp;</a><a id="fbWindow_btClose" class="fbSmallButton fbHover" title="Minimize Firebug">&nbsp;</a></div><div id="fbToolbar"><div id="fbToolbarContent"><span id="fbToolbarIcon"><a id="fbFirebugButton" class="fbIconButton" class="fbHover" target="_blank">&nbsp;</a></span><span id="fbToolbarButtons"><span id="fbFixedButtons"><a id="fbChrome_btInspect" class="fbButton fbHover" title="Click an element in the page to inspect">Inspect</a></span><span id="fbConsoleButtons" class="fbToolbarButtons"><a id="fbConsole_btClear" class="fbButton fbHover" title="Clear the console">Clear</a></span></span><span id="fbStatusBarBox"><span class="fbToolbarSeparator"></span></span></div></div><div id="fbPanelBarBox"><div id="fbPanelBar1" class="fbPanelBar"><a id="fbConsoleTab" class="fbTab fbHover"><span class="fbTabL"></span><span class="fbTabText">Console</span><span class="fbTabMenuTarget"></span><span class="fbTabR"></span></a><a id="fbHTMLTab" class="fbTab fbHover"><span class="fbTabL"></span><span class="fbTabText">HTML</span><span class="fbTabR"></span></a><a class="fbTab fbHover"><span class="fbTabL"></span><span class="fbTabText">CSS</span><span class="fbTabR"></span></a><a class="fbTab fbHover"><span class="fbTabL"></span><span class="fbTabText">Script</span><span class="fbTabR"></span></a><a class="fbTab fbHover"><span class="fbTabL"></span><span class="fbTabText">DOM</span><span class="fbTabR"></span></a></div><div id="fbPanelBar2Box" class="hide"><div id="fbPanelBar2" class="fbPanelBar"></div></div></div><div id="fbHSplitter">&nbsp;</div></td></tr><tr id="fbContent"><td id="fbPanelBox1"><div id="fbPanel1" class="fbFitHeight"><div id="fbConsole" class="fbPanel"></div><div id="fbHTML" class="fbPanel"></div></div></td><td id="fbPanelBox2" class="hide"><div id="fbVSplitter" class="fbVSplitter">&nbsp;</div><div id="fbPanel2" class="fbFitHeight"><div id="fbHTML_Style" class="fbPanel"></div><div id="fbHTML_Layout" class="fbPanel"></div><div id="fbHTML_DOM" class="fbPanel"></div></div><textarea id="fbLargeCommandLine" class="fbFitHeight"></textarea><div id="fbLargeCommandButtons"><a id="fbCommand_btRun" class="fbButton fbHover">Run</a><a id="fbCommand_btClear" class="fbButton fbHover">Clear</a><a id="fbSmallCommandLineIcon" class="fbSmallButton fbHover"></a></div></td></tr><tr id="fbBottom" class="hide"><td id="fbCommand" colspan="2"><div id="fbCommandBox"><div id="fbCommandIcon">&gt;&gt;&gt;</div><input id="fbCommandLine" name="fbCommandLine" type="text"/><a id="fbLargeCommandLineIcon" class="fbSmallButton fbHover"></a></div></td></tr></tbody></table><span id="fbMiniChrome"><span id="fbMiniContent"><span id="fbMiniIcon" title="Open Firebug Lite"></span><span id="fbMiniErrors" class="fbErrors"></span></span></span>'
-};
-
-// ************************************************************************************************
-}});
-
-// ************************************************************************************************
-FBL.initialize();
-// ************************************************************************************************
-
-})(); \ No newline at end of file
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/json-js/json2.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/json-js/json2.js
deleted file mode 100644
index 58384577..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/json-js/json2.js
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- json2.js
- 2015-05-03
-
- Public Domain.
-
- NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
-
- See http://www.JSON.org/js.html
-
-
- This code should be minified before deployment.
- See http://javascript.crockford.com/jsmin.html
-
- USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
- NOT CONTROL.
-
-
- This file creates a global JSON object containing two methods: stringify
- and parse. This file is provides the ES5 JSON capability to ES3 systems.
- If a project might run on IE8 or earlier, then this file should be included.
- This file does nothing on ES5 systems.
-
- JSON.stringify(value, replacer, space)
- value any JavaScript value, usually an object or array.
-
- replacer an optional parameter that determines how object
- values are stringified for objects. It can be a
- function or an array of strings.
-
- space an optional parameter that specifies the indentation
- of nested structures. If it is omitted, the text will
- be packed without extra whitespace. If it is a number,
- it will specify the number of spaces to indent at each
- level. If it is a string (such as '\t' or '&nbsp;'),
- it contains the characters used to indent at each level.
-
- This method produces a JSON text from a JavaScript value.
-
- When an object value is found, if the object contains a toJSON
- method, its toJSON method will be called and the result will be
- stringified. A toJSON method does not serialize: it returns the
- value represented by the name/value pair that should be serialized,
- or undefined if nothing should be serialized. The toJSON method
- will be passed the key associated with the value, and this will be
- bound to the value
-
- For example, this would serialize Dates as ISO strings.
-
- Date.prototype.toJSON = function (key) {
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10
- ? '0' + n
- : n;
- }
-
- return this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z';
- };
-
- You can provide an optional replacer method. It will be passed the
- key and value of each member, with this bound to the containing
- object. The value that is returned from your method will be
- serialized. If your method returns undefined, then the member will
- be excluded from the serialization.
-
- If the replacer parameter is an array of strings, then it will be
- used to select the members to be serialized. It filters the results
- such that only members with keys listed in the replacer array are
- stringified.
-
- Values that do not have JSON representations, such as undefined or
- functions, will not be serialized. Such values in objects will be
- dropped; in arrays they will be replaced with null. You can use
- a replacer function to replace those with JSON values.
- JSON.stringify(undefined) returns undefined.
-
- The optional space parameter produces a stringification of the
- value that is filled with line breaks and indentation to make it
- easier to read.
-
- If the space parameter is a non-empty string, then that string will
- be used for indentation. If the space parameter is a number, then
- the indentation will be that many spaces.
-
- Example:
-
- text = JSON.stringify(['e', {pluribus: 'unum'}]);
- // text is '["e",{"pluribus":"unum"}]'
-
-
- text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
- // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
-
- text = JSON.stringify([new Date()], function (key, value) {
- return this[key] instanceof Date
- ? 'Date(' + this[key] + ')'
- : value;
- });
- // text is '["Date(---current time---)"]'
-
-
- JSON.parse(text, reviver)
- This method parses a JSON text to produce an object or array.
- It can throw a SyntaxError exception.
-
- The optional reviver parameter is a function that can filter and
- transform the results. It receives each of the keys and values,
- and its return value is used instead of the original value.
- If it returns what it received, then the structure is not modified.
- If it returns undefined then the member is deleted.
-
- Example:
-
- // Parse the text. Values that look like ISO date strings will
- // be converted to Date objects.
-
- myData = JSON.parse(text, function (key, value) {
- var a;
- if (typeof value === 'string') {
- a =
-/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
- if (a) {
- return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
- +a[5], +a[6]));
- }
- }
- return value;
- });
-
- myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
- var d;
- if (typeof value === 'string' &&
- value.slice(0, 5) === 'Date(' &&
- value.slice(-1) === ')') {
- d = new Date(value.slice(5, -1));
- if (d) {
- return d;
- }
- }
- return value;
- });
-
-
- This is a reference implementation. You are free to copy, modify, or
- redistribute.
-*/
-
-/*jslint
- eval, for, this
-*/
-
-/*property
- JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
- getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
- lastIndex, length, parse, prototype, push, replace, slice, stringify,
- test, toJSON, toString, valueOf
-*/
-
-
-// Create a JSON object only if one does not already exist. We create the
-// methods in a closure to avoid creating global variables.
-
-if (typeof JSON !== 'object') {
- JSON = {};
-}
-
-(function () {
- 'use strict';
-
- var rx_one = /^[\],:{}\s]*$/,
- rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
- rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
- rx_four = /(?:^|:|,)(?:\s*\[)+/g,
- rx_escapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
-
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10
- ? '0' + n
- : n;
- }
-
- function this_value() {
- return this.valueOf();
- }
-
- if (typeof Date.prototype.toJSON !== 'function') {
-
- Date.prototype.toJSON = function () {
-
- return isFinite(this.valueOf())
- ? this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z'
- : null;
- };
-
- Boolean.prototype.toJSON = this_value;
- Number.prototype.toJSON = this_value;
- String.prototype.toJSON = this_value;
- }
-
- var gap,
- indent,
- meta,
- rep;
-
-
- function quote(string) {
-
-// If the string contains no control characters, no quote characters, and no
-// backslash characters, then we can safely slap some quotes around it.
-// Otherwise we must also replace the offending characters with safe escape
-// sequences.
-
- rx_escapable.lastIndex = 0;
- return rx_escapable.test(string)
- ? '"' + string.replace(rx_escapable, function (a) {
- var c = meta[a];
- return typeof c === 'string'
- ? c
- : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- }) + '"'
- : '"' + string + '"';
- }
-
-
- function str(key, holder) {
-
-// Produce a string from holder[key].
-
- var i, // The loop counter.
- k, // The member key.
- v, // The member value.
- length,
- mind = gap,
- partial,
- value = holder[key];
-
-// If the value has a toJSON method, call it to obtain a replacement value.
-
- if (value && typeof value === 'object' &&
- typeof value.toJSON === 'function') {
- value = value.toJSON(key);
- }
-
-// If we were called with a replacer function, then call the replacer to
-// obtain a replacement value.
-
- if (typeof rep === 'function') {
- value = rep.call(holder, key, value);
- }
-
-// What happens next depends on the value's type.
-
- switch (typeof value) {
- case 'string':
- return quote(value);
-
- case 'number':
-
-// JSON numbers must be finite. Encode non-finite numbers as null.
-
- return isFinite(value)
- ? String(value)
- : 'null';
-
- case 'boolean':
- case 'null':
-
-// If the value is a boolean or null, convert it to a string. Note:
-// typeof null does not produce 'null'. The case is included here in
-// the remote chance that this gets fixed someday.
-
- return String(value);
-
-// If the type is 'object', we might be dealing with an object or an array or
-// null.
-
- case 'object':
-
-// Due to a specification blunder in ECMAScript, typeof null is 'object',
-// so watch out for that case.
-
- if (!value) {
- return 'null';
- }
-
-// Make an array to hold the partial results of stringifying this object value.
-
- gap += indent;
- partial = [];
-
-// Is the value an array?
-
- if (Object.prototype.toString.apply(value) === '[object Array]') {
-
-// The value is an array. Stringify every element. Use null as a placeholder
-// for non-JSON values.
-
- length = value.length;
- for (i = 0; i < length; i += 1) {
- partial[i] = str(i, value) || 'null';
- }
-
-// Join all of the elements together, separated with commas, and wrap them in
-// brackets.
-
- v = partial.length === 0
- ? '[]'
- : gap
- ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
- : '[' + partial.join(',') + ']';
- gap = mind;
- return v;
- }
-
-// If the replacer is an array, use it to select the members to be stringified.
-
- if (rep && typeof rep === 'object') {
- length = rep.length;
- for (i = 0; i < length; i += 1) {
- if (typeof rep[i] === 'string') {
- k = rep[i];
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (
- gap
- ? ': '
- : ':'
- ) + v);
- }
- }
- }
- } else {
-
-// Otherwise, iterate through all of the keys in the object.
-
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (
- gap
- ? ': '
- : ':'
- ) + v);
- }
- }
- }
- }
-
-// Join all of the member texts together, separated with commas,
-// and wrap them in braces.
-
- v = partial.length === 0
- ? '{}'
- : gap
- ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
- : '{' + partial.join(',') + '}';
- gap = mind;
- return v;
- }
- }
-
-// If the JSON object does not yet have a stringify method, give it one.
-
- if (typeof JSON.stringify !== 'function') {
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"': '\\"',
- '\\': '\\\\'
- };
- JSON.stringify = function (value, replacer, space) {
-
-// The stringify method takes a value and an optional replacer, and an optional
-// space parameter, and returns a JSON text. The replacer can be a function
-// that can replace values, or an array of strings that will select the keys.
-// A default replacer method can be provided. Use of the space parameter can
-// produce text that is more easily readable.
-
- var i;
- gap = '';
- indent = '';
-
-// If the space parameter is a number, make an indent string containing that
-// many spaces.
-
- if (typeof space === 'number') {
- for (i = 0; i < space; i += 1) {
- indent += ' ';
- }
-
-// If the space parameter is a string, it will be used as the indent string.
-
- } else if (typeof space === 'string') {
- indent = space;
- }
-
-// If there is a replacer, it must be a function or an array.
-// Otherwise, throw an error.
-
- rep = replacer;
- if (replacer && typeof replacer !== 'function' &&
- (typeof replacer !== 'object' ||
- typeof replacer.length !== 'number')) {
- throw new Error('JSON.stringify');
- }
-
-// Make a fake root object containing our value under the key of ''.
-// Return the result of stringifying the value.
-
- return str('', {'': value});
- };
- }
-
-
-// If the JSON object does not yet have a parse method, give it one.
-
- if (typeof JSON.parse !== 'function') {
- JSON.parse = function (text, reviver) {
-
-// The parse method takes a text and an optional reviver function, and returns
-// a JavaScript value if the text is a valid JSON text.
-
- var j;
-
- function walk(holder, key) {
-
-// The walk method is used to recursively walk the resulting structure so
-// that modifications can be made.
-
- var k, v, value = holder[key];
- if (value && typeof value === 'object') {
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }
-
-
-// Parsing happens in four stages. In the first stage, we replace certain
-// Unicode characters with escape sequences. JavaScript handles many characters
-// incorrectly, either silently deleting them, or treating them as line endings.
-
- text = String(text);
- rx_dangerous.lastIndex = 0;
- if (rx_dangerous.test(text)) {
- text = text.replace(rx_dangerous, function (a) {
- return '\\u' +
- ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- });
- }
-
-// In the second stage, we run the text against regular expressions that look
-// for non-JSON patterns. We are especially concerned with '()' and 'new'
-// because they can cause invocation, and '=' because it can cause mutation.
-// But just to be safe, we want to reject all unexpected forms.
-
-// We split the second stage into 4 regexp operations in order to work around
-// crippling inefficiencies in IE's and Safari's regexp engines. First we
-// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
-// replace all simple value tokens with ']' characters. Third, we delete all
-// open brackets that follow a colon or comma or that begin the text. Finally,
-// we look to see that the remaining characters are only whitespace or ']' or
-// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
-
- if (
- rx_one.test(
- text
- .replace(rx_two, '@')
- .replace(rx_three, ']')
- .replace(rx_four, '')
- )
- ) {
-
-// In the third stage we use the eval function to compile the text into a
-// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
-// in JavaScript: it can begin a block or an object literal. We wrap the text
-// in parens to eliminate the ambiguity.
-
- j = eval('(' + text + ')');
-
-// In the optional fourth stage, we recursively walk the new structure, passing
-// each name/value pair to a reviver function for possible transformation.
-
- return typeof reviver === 'function'
- ? walk({'': j}, '')
- : j;
- }
-
-// If the text is not JSON parseable, then a SyntaxError is thrown.
-
- throw new SyntaxError('JSON.parse');
- };
- }
-}());
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/LICENSE b/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/LICENSE
deleted file mode 100644
index 447239f3..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/LICENSE
+++ /dev/null
@@ -1,23 +0,0 @@
-Copyright (c) 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative
-Reporters & Editors
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/arrays.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/arrays.js
deleted file mode 100644
index 748edea4..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/arrays.js
+++ /dev/null
@@ -1,555 +0,0 @@
-(function() {
- var _ = typeof require == 'function' ? require('..') : window._;
-
- QUnit.module('Arrays');
-
- QUnit.test('first', function(assert) {
- assert.equal(_.first([1, 2, 3]), 1, 'can pull out the first element of an array');
- assert.equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"');
- assert.deepEqual(_.first([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)');
- assert.deepEqual(_.first([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)');
- assert.deepEqual(_.first([1, 2, 3], 2), [1, 2], 'can fetch the first n elements');
- assert.deepEqual(_.first([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length');
- var result = (function(){ return _.first(arguments); }(4, 3, 2, 1));
- assert.equal(result, 4, 'works on an arguments object');
- result = _.map([[1, 2, 3], [1, 2, 3]], _.first);
- assert.deepEqual(result, [1, 1], 'works well with _.map');
- assert.equal(_.first(null), void 0, 'returns undefined when called on null');
- });
-
- QUnit.test('head', function(assert) {
- assert.strictEqual(_.head, _.first, 'is an alias for first');
- });
-
- QUnit.test('take', function(assert) {
- assert.strictEqual(_.take, _.first, 'is an alias for first');
- });
-
- QUnit.test('rest', function(assert) {
- var numbers = [1, 2, 3, 4];
- assert.deepEqual(_.rest(numbers), [2, 3, 4], 'fetches all but the first element');
- assert.deepEqual(_.rest(numbers, 0), [1, 2, 3, 4], 'returns the whole array when index is 0');
- assert.deepEqual(_.rest(numbers, 2), [3, 4], 'returns elements starting at the given index');
- var result = (function(){ return _(arguments).rest(); }(1, 2, 3, 4));
- assert.deepEqual(result, [2, 3, 4], 'works on an arguments object');
- result = _.map([[1, 2, 3], [1, 2, 3]], _.rest);
- assert.deepEqual(_.flatten(result), [2, 3, 2, 3], 'works well with _.map');
- });
-
- QUnit.test('tail', function(assert) {
- assert.strictEqual(_.tail, _.rest, 'is an alias for rest');
- });
-
- QUnit.test('drop', function(assert) {
- assert.strictEqual(_.drop, _.rest, 'is an alias for rest');
- });
-
- QUnit.test('initial', function(assert) {
- assert.deepEqual(_.initial([1, 2, 3, 4, 5]), [1, 2, 3, 4], 'returns all but the last element');
- assert.deepEqual(_.initial([1, 2, 3, 4], 2), [1, 2], 'returns all but the last n elements');
- assert.deepEqual(_.initial([1, 2, 3, 4], 6), [], 'returns an empty array when n > length');
- var result = (function(){ return _(arguments).initial(); }(1, 2, 3, 4));
- assert.deepEqual(result, [1, 2, 3], 'works on an arguments object');
- result = _.map([[1, 2, 3], [1, 2, 3]], _.initial);
- assert.deepEqual(_.flatten(result), [1, 2, 1, 2], 'works well with _.map');
- });
-
- QUnit.test('last', function(assert) {
- assert.equal(_.last([1, 2, 3]), 3, 'can pull out the last element of an array');
- assert.equal(_([1, 2, 3]).last(), 3, 'can perform OO-style "last()"');
- assert.deepEqual(_.last([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)');
- assert.deepEqual(_.last([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)');
- assert.deepEqual(_.last([1, 2, 3], 2), [2, 3], 'can fetch the last n elements');
- assert.deepEqual(_.last([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length');
- var result = (function(){ return _(arguments).last(); }(1, 2, 3, 4));
- assert.equal(result, 4, 'works on an arguments object');
- result = _.map([[1, 2, 3], [1, 2, 3]], _.last);
- assert.deepEqual(result, [3, 3], 'works well with _.map');
- assert.equal(_.last(null), void 0, 'returns undefined when called on null');
- });
-
- QUnit.test('compact', function(assert) {
- assert.deepEqual(_.compact([1, false, null, 0, '', void 0, NaN, 2]), [1, 2], 'removes all falsy values');
- var result = (function(){ return _.compact(arguments); }(0, 1, false, 2, false, 3));
- assert.deepEqual(result, [1, 2, 3], 'works on an arguments object');
- result = _.map([[1, false, false], [false, false, 3]], _.compact);
- assert.deepEqual(result, [[1], [3]], 'works well with _.map');
- });
-
- QUnit.test('flatten', function(assert) {
- assert.deepEqual(_.flatten(null), [], 'supports null');
- assert.deepEqual(_.flatten(void 0), [], 'supports undefined');
-
- assert.deepEqual(_.flatten([[], [[]], []]), [], 'supports empty arrays');
- assert.deepEqual(_.flatten([[], [[]], []], true), [[]], 'can shallowly flatten empty arrays');
-
- var list = [1, [2], [3, [[[4]]]]];
- assert.deepEqual(_.flatten(list), [1, 2, 3, 4], 'can flatten nested arrays');
- assert.deepEqual(_.flatten(list, true), [1, 2, 3, [[[4]]]], 'can shallowly flatten nested arrays');
- var result = (function(){ return _.flatten(arguments); }(1, [2], [3, [[[4]]]]));
- assert.deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
- list = [[1], [2], [3], [[4]]];
- assert.deepEqual(_.flatten(list, true), [1, 2, 3, [4]], 'can shallowly flatten arrays containing only other arrays');
-
- assert.equal(_.flatten([_.range(10), _.range(10), 5, 1, 3], true).length, 23, 'can flatten medium length arrays');
- assert.equal(_.flatten([_.range(10), _.range(10), 5, 1, 3]).length, 23, 'can shallowly flatten medium length arrays');
- assert.equal(_.flatten([new Array(1000000), _.range(56000), 5, 1, 3]).length, 1056003, 'can handle massive arrays');
- assert.equal(_.flatten([new Array(1000000), _.range(56000), 5, 1, 3], true).length, 1056003, 'can handle massive arrays in shallow mode');
-
- var x = _.range(100000);
- for (var i = 0; i < 1000; i++) x = [x];
- assert.deepEqual(_.flatten(x), _.range(100000), 'can handle very deep arrays');
- assert.deepEqual(_.flatten(x, true), x[0], 'can handle very deep arrays in shallow mode');
- });
-
- QUnit.test('without', function(assert) {
- var list = [1, 2, 1, 0, 3, 1, 4];
- assert.deepEqual(_.without(list, 0, 1), [2, 3, 4], 'removes all instances of the given values');
- var result = (function(){ return _.without(arguments, 0, 1); }(1, 2, 1, 0, 3, 1, 4));
- assert.deepEqual(result, [2, 3, 4], 'works on an arguments object');
-
- list = [{one: 1}, {two: 2}];
- assert.deepEqual(_.without(list, {one: 1}), list, 'compares objects by reference (value case)');
- assert.deepEqual(_.without(list, list[0]), [{two: 2}], 'compares objects by reference (reference case)');
- });
-
- QUnit.test('sortedIndex', function(assert) {
- var numbers = [10, 20, 30, 40, 50];
- var indexFor35 = _.sortedIndex(numbers, 35);
- assert.equal(indexFor35, 3, 'finds the index at which a value should be inserted to retain order');
- var indexFor30 = _.sortedIndex(numbers, 30);
- assert.equal(indexFor30, 2, 'finds the smallest index at which a value could be inserted to retain order');
-
- var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}];
- var iterator = function(obj){ return obj.x; };
- assert.strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2, 'uses the result of `iterator` for order comparisons');
- assert.strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3, 'when `iterator` is a string, uses that key for order comparisons');
-
- var context = {1: 2, 2: 3, 3: 4};
- iterator = function(obj){ return this[obj]; };
- assert.strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1, 'can execute its iterator in the given context');
-
- var values = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287,
- 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647];
- var largeArray = Array(Math.pow(2, 32) - 1);
- var length = values.length;
- // Sparsely populate `array`
- while (length--) {
- largeArray[values[length]] = values[length];
- }
- assert.equal(_.sortedIndex(largeArray, 2147483648), 2147483648, 'works with large indexes');
- });
-
- QUnit.test('uniq', function(assert) {
- var list = [1, 2, 1, 3, 1, 4];
- assert.deepEqual(_.uniq(list), [1, 2, 3, 4], 'can find the unique values of an unsorted array');
- list = [1, 1, 1, 2, 2, 3];
- assert.deepEqual(_.uniq(list, true), [1, 2, 3], 'can find the unique values of a sorted array faster');
-
- list = [{name: 'Moe'}, {name: 'Curly'}, {name: 'Larry'}, {name: 'Curly'}];
- var expected = [{name: 'Moe'}, {name: 'Curly'}, {name: 'Larry'}];
- var iterator = function(stooge) { return stooge.name; };
- assert.deepEqual(_.uniq(list, false, iterator), expected, 'uses the result of `iterator` for uniqueness comparisons (unsorted case)');
- assert.deepEqual(_.uniq(list, iterator), expected, '`sorted` argument defaults to false when omitted');
- assert.deepEqual(_.uniq(list, 'name'), expected, 'when `iterator` is a string, uses that key for comparisons (unsorted case)');
-
- list = [{score: 8}, {score: 10}, {score: 10}];
- expected = [{score: 8}, {score: 10}];
- iterator = function(item) { return item.score; };
- assert.deepEqual(_.uniq(list, true, iterator), expected, 'uses the result of `iterator` for uniqueness comparisons (sorted case)');
- assert.deepEqual(_.uniq(list, true, 'score'), expected, 'when `iterator` is a string, uses that key for comparisons (sorted case)');
-
- assert.deepEqual(_.uniq([{0: 1}, {0: 1}, {0: 1}, {0: 2}], 0), [{0: 1}, {0: 2}], 'can use falsey pluck like iterator');
-
- var result = (function(){ return _.uniq(arguments); }(1, 2, 1, 3, 1, 4));
- assert.deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
-
- var a = {}, b = {}, c = {};
- assert.deepEqual(_.uniq([a, b, a, b, c]), [a, b, c], 'works on values that can be tested for equivalency but not ordered');
-
- assert.deepEqual(_.uniq(null), [], 'returns an empty array when `array` is not iterable');
-
- var context = {};
- list = [3];
- _.uniq(list, function(value, index, array) {
- assert.strictEqual(this, context, 'executes its iterator in the given context');
- assert.strictEqual(value, 3, 'passes its iterator the value');
- assert.strictEqual(index, 0, 'passes its iterator the index');
- assert.strictEqual(array, list, 'passes its iterator the entire array');
- }, context);
-
- });
-
- QUnit.test('unique', function(assert) {
- assert.strictEqual(_.unique, _.uniq, 'is an alias for uniq');
- });
-
- QUnit.test('intersection', function(assert) {
- var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho'];
- assert.deepEqual(_.intersection(stooges, leaders), ['moe'], 'can find the set intersection of two arrays');
- assert.deepEqual(_(stooges).intersection(leaders), ['moe'], 'can perform an OO-style intersection');
- var result = (function(){ return _.intersection(arguments, leaders); }('moe', 'curly', 'larry'));
- assert.deepEqual(result, ['moe'], 'works on an arguments object');
- var theSixStooges = ['moe', 'moe', 'curly', 'curly', 'larry', 'larry'];
- assert.deepEqual(_.intersection(theSixStooges, leaders), ['moe'], 'returns a duplicate-free array');
- result = _.intersection([2, 4, 3, 1], [1, 2, 3]);
- assert.deepEqual(result, [2, 3, 1], 'preserves the order of the first array');
- result = _.intersection(null, [1, 2, 3]);
- assert.deepEqual(result, [], 'returns an empty array when passed null as the first argument');
- result = _.intersection([1, 2, 3], null);
- assert.deepEqual(result, [], 'returns an empty array when passed null as an argument beyond the first');
- });
-
- QUnit.test('union', function(assert) {
- var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]);
- assert.deepEqual(result, [1, 2, 3, 30, 40], 'can find the union of a list of arrays');
-
- result = _([1, 2, 3]).union([2, 30, 1], [1, 40]);
- assert.deepEqual(result, [1, 2, 3, 30, 40], 'can perform an OO-style union');
-
- result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]);
- assert.deepEqual(result, [1, 2, 3, 30, 40, [1]], 'can find the union of a list of nested arrays');
-
- result = _.union([10, 20], [1, 30, 10], [0, 40]);
- assert.deepEqual(result, [10, 20, 1, 30, 0, 40], 'orders values by their first encounter');
-
- result = (function(){ return _.union(arguments, [2, 30, 1], [1, 40]); }(1, 2, 3));
- assert.deepEqual(result, [1, 2, 3, 30, 40], 'works on an arguments object');
-
- assert.deepEqual(_.union([1, 2, 3], 4), [1, 2, 3], 'restricts the union to arrays only');
- });
-
- QUnit.test('difference', function(assert) {
- var result = _.difference([1, 2, 3], [2, 30, 40]);
- assert.deepEqual(result, [1, 3], 'can find the difference of two arrays');
-
- result = _([1, 2, 3]).difference([2, 30, 40]);
- assert.deepEqual(result, [1, 3], 'can perform an OO-style difference');
-
- result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]);
- assert.deepEqual(result, [3, 4], 'can find the difference of three arrays');
-
- result = _.difference([8, 9, 3, 1], [3, 8]);
- assert.deepEqual(result, [9, 1], 'preserves the order of the first array');
-
- result = (function(){ return _.difference(arguments, [2, 30, 40]); }(1, 2, 3));
- assert.deepEqual(result, [1, 3], 'works on an arguments object');
-
- result = _.difference([1, 2, 3], 1);
- assert.deepEqual(result, [1, 2, 3], 'restrict the difference to arrays only');
- });
-
- QUnit.test('zip', function(assert) {
- var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true];
- assert.deepEqual(_.zip(names, ages, leaders), [
- ['moe', 30, true],
- ['larry', 40, void 0],
- ['curly', 50, void 0]
- ], 'zipped together arrays of different lengths');
-
- var stooges = _.zip(['moe', 30, 'stooge 1'], ['larry', 40, 'stooge 2'], ['curly', 50, 'stooge 3']);
- assert.deepEqual(stooges, [['moe', 'larry', 'curly'], [30, 40, 50], ['stooge 1', 'stooge 2', 'stooge 3']], 'zipped pairs');
-
- // In the case of different lengths of the tuples, undefined values
- // should be used as placeholder
- stooges = _.zip(['moe', 30], ['larry', 40], ['curly', 50, 'extra data']);
- assert.deepEqual(stooges, [['moe', 'larry', 'curly'], [30, 40, 50], [void 0, void 0, 'extra data']], 'zipped pairs with empties');
-
- var empty = _.zip([]);
- assert.deepEqual(empty, [], 'unzipped empty');
-
- assert.deepEqual(_.zip(null), [], 'handles null');
- assert.deepEqual(_.zip(), [], '_.zip() returns []');
- });
-
- QUnit.test('unzip', function(assert) {
- assert.deepEqual(_.unzip(null), [], 'handles null');
-
- assert.deepEqual(_.unzip([['a', 'b'], [1, 2]]), [['a', 1], ['b', 2]]);
-
- // complements zip
- var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
- assert.deepEqual(_.unzip(zipped), [['fred', 'barney'], [30, 40], [true, false]]);
-
- zipped = _.zip(['moe', 30], ['larry', 40], ['curly', 50, 'extra data']);
- assert.deepEqual(_.unzip(zipped), [['moe', 30, void 0], ['larry', 40, void 0], ['curly', 50, 'extra data']], 'Uses length of largest array');
- });
-
- QUnit.test('object', function(assert) {
- var result = _.object(['moe', 'larry', 'curly'], [30, 40, 50]);
- var shouldBe = {moe: 30, larry: 40, curly: 50};
- assert.deepEqual(result, shouldBe, 'two arrays zipped together into an object');
-
- result = _.object([['one', 1], ['two', 2], ['three', 3]]);
- shouldBe = {one: 1, two: 2, three: 3};
- assert.deepEqual(result, shouldBe, 'an array of pairs zipped together into an object');
-
- var stooges = {moe: 30, larry: 40, curly: 50};
- assert.deepEqual(_.object(_.pairs(stooges)), stooges, 'an object converted to pairs and back to an object');
-
- assert.deepEqual(_.object(null), {}, 'handles nulls');
- });
-
- QUnit.test('indexOf', function(assert) {
- var numbers = [1, 2, 3];
- assert.equal(_.indexOf(numbers, 2), 1, 'can compute indexOf');
- var result = (function(){ return _.indexOf(arguments, 2); }(1, 2, 3));
- assert.equal(result, 1, 'works on an arguments object');
-
- _.each([null, void 0, [], false], function(val) {
- var msg = 'Handles: ' + (_.isArray(val) ? '[]' : val);
- assert.equal(_.indexOf(val, 2), -1, msg);
- assert.equal(_.indexOf(val, 2, -1), -1, msg);
- assert.equal(_.indexOf(val, 2, -20), -1, msg);
- assert.equal(_.indexOf(val, 2, 15), -1, msg);
- });
-
- var num = 35;
- numbers = [10, 20, 30, 40, 50];
- var index = _.indexOf(numbers, num, true);
- assert.equal(index, -1, '35 is not in the list');
-
- numbers = [10, 20, 30, 40, 50]; num = 40;
- index = _.indexOf(numbers, num, true);
- assert.equal(index, 3, '40 is in the list');
-
- numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40;
- assert.equal(_.indexOf(numbers, num, true), 1, '40 is in the list');
- assert.equal(_.indexOf(numbers, 6, true), -1, '6 isnt in the list');
- assert.equal(_.indexOf([1, 2, 5, 4, 6, 7], 5, true), -1, 'sorted indexOf doesn\'t uses binary search');
- assert.ok(_.every(['1', [], {}, null], function() {
- return _.indexOf(numbers, num, {}) === 1;
- }), 'non-nums as fromIndex make indexOf assume sorted');
-
- numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
- index = _.indexOf(numbers, 2, 5);
- assert.equal(index, 7, 'supports the fromIndex argument');
-
- index = _.indexOf([,,, 0], void 0);
- assert.equal(index, 0, 'treats sparse arrays as if they were dense');
-
- var array = [1, 2, 3, 1, 2, 3];
- assert.strictEqual(_.indexOf(array, 1, -3), 3, 'neg `fromIndex` starts at the right index');
- assert.strictEqual(_.indexOf(array, 1, -2), -1, 'neg `fromIndex` starts at the right index');
- assert.strictEqual(_.indexOf(array, 2, -3), 4);
- _.each([-6, -8, -Infinity], function(fromIndex) {
- assert.strictEqual(_.indexOf(array, 1, fromIndex), 0);
- });
- assert.strictEqual(_.indexOf([1, 2, 3], 1, true), 0);
-
- index = _.indexOf([], void 0, true);
- assert.equal(index, -1, 'empty array with truthy `isSorted` returns -1');
- });
-
- QUnit.test('indexOf with NaN', function(assert) {
- assert.strictEqual(_.indexOf([1, 2, NaN, NaN], NaN), 2, 'Expected [1, 2, NaN] to contain NaN');
- assert.strictEqual(_.indexOf([1, 2, Infinity], NaN), -1, 'Expected [1, 2, NaN] to contain NaN');
-
- assert.strictEqual(_.indexOf([1, 2, NaN, NaN], NaN, 1), 2, 'startIndex does not affect result');
- assert.strictEqual(_.indexOf([1, 2, NaN, NaN], NaN, -2), 2, 'startIndex does not affect result');
-
- (function() {
- assert.strictEqual(_.indexOf(arguments, NaN), 2, 'Expected arguments [1, 2, NaN] to contain NaN');
- }(1, 2, NaN, NaN));
- });
-
- QUnit.test('indexOf with +- 0', function(assert) {
- _.each([-0, +0], function(val) {
- assert.strictEqual(_.indexOf([1, 2, val, val], val), 2);
- assert.strictEqual(_.indexOf([1, 2, val, val], -val), 2);
- });
- });
-
- QUnit.test('lastIndexOf', function(assert) {
- var numbers = [1, 0, 1];
- var falsey = [void 0, '', 0, false, NaN, null, void 0];
- assert.equal(_.lastIndexOf(numbers, 1), 2);
-
- numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0];
- numbers.lastIndexOf = null;
- assert.equal(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function');
- assert.equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element');
- var result = (function(){ return _.lastIndexOf(arguments, 1); }(1, 0, 1, 0, 0, 1, 0, 0, 0));
- assert.equal(result, 5, 'works on an arguments object');
-
- _.each([null, void 0, [], false], function(val) {
- var msg = 'Handles: ' + (_.isArray(val) ? '[]' : val);
- assert.equal(_.lastIndexOf(val, 2), -1, msg);
- assert.equal(_.lastIndexOf(val, 2, -1), -1, msg);
- assert.equal(_.lastIndexOf(val, 2, -20), -1, msg);
- assert.equal(_.lastIndexOf(val, 2, 15), -1, msg);
- });
-
- numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
- var index = _.lastIndexOf(numbers, 2, 2);
- assert.equal(index, 1, 'supports the fromIndex argument');
-
- var array = [1, 2, 3, 1, 2, 3];
-
- assert.strictEqual(_.lastIndexOf(array, 1, 0), 0, 'starts at the correct from idx');
- assert.strictEqual(_.lastIndexOf(array, 3), 5, 'should return the index of the last matched value');
- assert.strictEqual(_.lastIndexOf(array, 4), -1, 'should return `-1` for an unmatched value');
-
- assert.strictEqual(_.lastIndexOf(array, 1, 2), 0, 'should work with a positive `fromIndex`');
-
- _.each([6, 8, Math.pow(2, 32), Infinity], function(fromIndex) {
- assert.strictEqual(_.lastIndexOf(array, void 0, fromIndex), -1);
- assert.strictEqual(_.lastIndexOf(array, 1, fromIndex), 3);
- assert.strictEqual(_.lastIndexOf(array, '', fromIndex), -1);
- });
-
- var expected = _.map(falsey, function(value) {
- return typeof value == 'number' ? -1 : 5;
- });
-
- var actual = _.map(falsey, function(fromIndex) {
- return _.lastIndexOf(array, 3, fromIndex);
- });
-
- assert.deepEqual(actual, expected, 'should treat falsey `fromIndex` values, except `0` and `NaN`, as `array.length`');
- assert.strictEqual(_.lastIndexOf(array, 3, '1'), 5, 'should treat non-number `fromIndex` values as `array.length`');
- assert.strictEqual(_.lastIndexOf(array, 3, true), 5, 'should treat non-number `fromIndex` values as `array.length`');
-
- assert.strictEqual(_.lastIndexOf(array, 2, -3), 1, 'should work with a negative `fromIndex`');
- assert.strictEqual(_.lastIndexOf(array, 1, -3), 3, 'neg `fromIndex` starts at the right index');
-
- assert.deepEqual(_.map([-6, -8, -Infinity], function(fromIndex) {
- return _.lastIndexOf(array, 1, fromIndex);
- }), [0, -1, -1]);
- });
-
- QUnit.test('lastIndexOf with NaN', function(assert) {
- assert.strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN), 3, 'Expected [1, 2, NaN] to contain NaN');
- assert.strictEqual(_.lastIndexOf([1, 2, Infinity], NaN), -1, 'Expected [1, 2, NaN] to contain NaN');
-
- assert.strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN, 2), 2, 'fromIndex does not affect result');
- assert.strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN, -2), 2, 'fromIndex does not affect result');
-
- (function() {
- assert.strictEqual(_.lastIndexOf(arguments, NaN), 3, 'Expected arguments [1, 2, NaN] to contain NaN');
- }(1, 2, NaN, NaN));
- });
-
- QUnit.test('lastIndexOf with +- 0', function(assert) {
- _.each([-0, +0], function(val) {
- assert.strictEqual(_.lastIndexOf([1, 2, val, val], val), 3);
- assert.strictEqual(_.lastIndexOf([1, 2, val, val], -val), 3);
- assert.strictEqual(_.lastIndexOf([-1, 1, 2], -val), -1);
- });
- });
-
- QUnit.test('findIndex', function(assert) {
- var objects = [
- {a: 0, b: 0},
- {a: 1, b: 1},
- {a: 2, b: 2},
- {a: 0, b: 0}
- ];
-
- assert.equal(_.findIndex(objects, function(obj) {
- return obj.a === 0;
- }), 0);
-
- assert.equal(_.findIndex(objects, function(obj) {
- return obj.b * obj.a === 4;
- }), 2);
-
- assert.equal(_.findIndex(objects, 'a'), 1, 'Uses lookupIterator');
-
- assert.equal(_.findIndex(objects, function(obj) {
- return obj.b * obj.a === 5;
- }), -1);
-
- assert.equal(_.findIndex(null, _.noop), -1);
- assert.strictEqual(_.findIndex(objects, function(a) {
- return a.foo === null;
- }), -1);
- _.findIndex([{a: 1}], function(a, key, obj) {
- assert.equal(key, 0);
- assert.deepEqual(obj, [{a: 1}]);
- assert.strictEqual(this, objects, 'called with context');
- }, objects);
-
- var sparse = [];
- sparse[20] = {a: 2, b: 2};
- assert.equal(_.findIndex(sparse, function(obj) {
- return obj && obj.b * obj.a === 4;
- }), 20, 'Works with sparse arrays');
-
- var array = [1, 2, 3, 4];
- array.match = 55;
- assert.strictEqual(_.findIndex(array, function(x) { return x === 55; }), -1, 'doesn\'t match array-likes keys');
- });
-
- QUnit.test('findLastIndex', function(assert) {
- var objects = [
- {a: 0, b: 0},
- {a: 1, b: 1},
- {a: 2, b: 2},
- {a: 0, b: 0}
- ];
-
- assert.equal(_.findLastIndex(objects, function(obj) {
- return obj.a === 0;
- }), 3);
-
- assert.equal(_.findLastIndex(objects, function(obj) {
- return obj.b * obj.a === 4;
- }), 2);
-
- assert.equal(_.findLastIndex(objects, 'a'), 2, 'Uses lookupIterator');
-
- assert.equal(_.findLastIndex(objects, function(obj) {
- return obj.b * obj.a === 5;
- }), -1);
-
- assert.equal(_.findLastIndex(null, _.noop), -1);
- assert.strictEqual(_.findLastIndex(objects, function(a) {
- return a.foo === null;
- }), -1);
- _.findLastIndex([{a: 1}], function(a, key, obj) {
- assert.equal(key, 0);
- assert.deepEqual(obj, [{a: 1}]);
- assert.strictEqual(this, objects, 'called with context');
- }, objects);
-
- var sparse = [];
- sparse[20] = {a: 2, b: 2};
- assert.equal(_.findLastIndex(sparse, function(obj) {
- return obj && obj.b * obj.a === 4;
- }), 20, 'Works with sparse arrays');
-
- var array = [1, 2, 3, 4];
- array.match = 55;
- assert.strictEqual(_.findLastIndex(array, function(x) { return x === 55; }), -1, 'doesn\'t match array-likes keys');
- });
-
- QUnit.test('range', function(assert) {
- assert.deepEqual(_.range(0), [], 'range with 0 as a first argument generates an empty array');
- assert.deepEqual(_.range(4), [0, 1, 2, 3], 'range with a single positive argument generates an array of elements 0,1,2,...,n-1');
- assert.deepEqual(_.range(5, 8), [5, 6, 7], 'range with two arguments a &amp; b, a&lt;b generates an array of elements a,a+1,a+2,...,b-2,b-1');
- assert.deepEqual(_.range(3, 10, 3), [3, 6, 9], 'range with three arguments a &amp; b &amp; c, c &lt; b-a, a &lt; b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) &lt; c');
- assert.deepEqual(_.range(3, 10, 15), [3], 'range with three arguments a &amp; b &amp; c, c &gt; b-a, a &lt; b generates an array with a single element, equal to a');
- assert.deepEqual(_.range(12, 7, -2), [12, 10, 8], 'range with three arguments a &amp; b &amp; c, a &gt; b, c &lt; 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b');
- assert.deepEqual(_.range(0, -10, -1), [0, -1, -2, -3, -4, -5, -6, -7, -8, -9], 'final example in the Python docs');
- assert.strictEqual(1 / _.range(-0, 1)[0], -Infinity, 'should preserve -0');
- assert.deepEqual(_.range(8, 5), [8, 7, 6], 'negative range generates descending array');
- assert.deepEqual(_.range(-3), [0, -1, -2], 'negative range generates descending array');
- });
-
- QUnit.test('chunk', function(assert) {
- assert.deepEqual(_.chunk([], 2), [], 'chunk for empty array returns an empty array');
-
- assert.deepEqual(_.chunk([1, 2, 3], 0), [], 'chunk into parts of 0 elements returns empty array');
- assert.deepEqual(_.chunk([1, 2, 3], -1), [], 'chunk into parts of negative amount of elements returns an empty array');
- assert.deepEqual(_.chunk([1, 2, 3]), [], 'defaults to empty array (chunk size 0)');
-
- assert.deepEqual(_.chunk([1, 2, 3], 1), [[1], [2], [3]], 'chunk into parts of 1 elements returns original array');
-
- assert.deepEqual(_.chunk([1, 2, 3], 3), [[1, 2, 3]], 'chunk into parts of current array length elements returns the original array');
- assert.deepEqual(_.chunk([1, 2, 3], 5), [[1, 2, 3]], 'chunk into parts of more then current array length elements returns the original array');
-
- assert.deepEqual(_.chunk([10, 20, 30, 40, 50, 60, 70], 2), [[10, 20], [30, 40], [50, 60], [70]], 'chunk into parts of less then current array length elements');
- assert.deepEqual(_.chunk([10, 20, 30, 40, 50, 60, 70], 3), [[10, 20, 30], [40, 50, 60], [70]], 'chunk into parts of less then current array length elements');
- });
-}());
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/chaining.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/chaining.js
deleted file mode 100644
index 6ad21dcf..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/chaining.js
+++ /dev/null
@@ -1,99 +0,0 @@
-(function() {
- var _ = typeof require == 'function' ? require('..') : window._;
-
- QUnit.module('Chaining');
-
- QUnit.test('map/flatten/reduce', function(assert) {
- var lyrics = [
- 'I\'m a lumberjack and I\'m okay',
- 'I sleep all night and I work all day',
- 'He\'s a lumberjack and he\'s okay',
- 'He sleeps all night and he works all day'
- ];
- var counts = _(lyrics).chain()
- .map(function(line) { return line.split(''); })
- .flatten()
- .reduce(function(hash, l) {
- hash[l] = hash[l] || 0;
- hash[l]++;
- return hash;
- }, {})
- .value();
- assert.equal(counts.a, 16, 'counted all the letters in the song');
- assert.equal(counts.e, 10, 'counted all the letters in the song');
- });
-
- QUnit.test('select/reject/sortBy', function(assert) {
- var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
- numbers = _(numbers).chain().select(function(n) {
- return n % 2 === 0;
- }).reject(function(n) {
- return n % 4 === 0;
- }).sortBy(function(n) {
- return -n;
- }).value();
- assert.deepEqual(numbers, [10, 6, 2], 'filtered and reversed the numbers');
- });
-
- QUnit.test('select/reject/sortBy in functional style', function(assert) {
- var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
- numbers = _.chain(numbers).select(function(n) {
- return n % 2 === 0;
- }).reject(function(n) {
- return n % 4 === 0;
- }).sortBy(function(n) {
- return -n;
- }).value();
- assert.deepEqual(numbers, [10, 6, 2], 'filtered and reversed the numbers');
- });
-
- QUnit.test('reverse/concat/unshift/pop/map', function(assert) {
- var numbers = [1, 2, 3, 4, 5];
- numbers = _(numbers).chain()
- .reverse()
- .concat([5, 5, 5])
- .unshift(17)
- .pop()
- .map(function(n){ return n * 2; })
- .value();
- assert.deepEqual(numbers, [34, 10, 8, 6, 4, 2, 10, 10], 'can chain together array functions.');
- });
-
- QUnit.test('splice', function(assert) {
- var instance = _([1, 2, 3, 4, 5]).chain();
- assert.deepEqual(instance.splice(1, 3).value(), [1, 5]);
- assert.deepEqual(instance.splice(1, 0).value(), [1, 5]);
- assert.deepEqual(instance.splice(1, 1).value(), [1]);
- assert.deepEqual(instance.splice(0, 1).value(), [], '#397 Can create empty array');
- });
-
- QUnit.test('shift', function(assert) {
- var instance = _([1, 2, 3]).chain();
- assert.deepEqual(instance.shift().value(), [2, 3]);
- assert.deepEqual(instance.shift().value(), [3]);
- assert.deepEqual(instance.shift().value(), [], '#397 Can create empty array');
- });
-
- QUnit.test('pop', function(assert) {
- var instance = _([1, 2, 3]).chain();
- assert.deepEqual(instance.pop().value(), [1, 2]);
- assert.deepEqual(instance.pop().value(), [1]);
- assert.deepEqual(instance.pop().value(), [], '#397 Can create empty array');
- });
-
- QUnit.test('chaining works in small stages', function(assert) {
- var o = _([1, 2, 3, 4]).chain();
- assert.deepEqual(o.filter(function(i) { return i < 3; }).value(), [1, 2]);
- assert.deepEqual(o.filter(function(i) { return i > 2; }).value(), [3, 4]);
- });
-
- QUnit.test('#1562: Engine proxies for chained functions', function(assert) {
- var wrapped = _(512);
- assert.strictEqual(wrapped.toJSON(), 512);
- assert.strictEqual(wrapped.valueOf(), 512);
- assert.strictEqual(+wrapped, 512);
- assert.strictEqual(wrapped.toString(), '512');
- assert.strictEqual('' + wrapped, '512');
- });
-
-}());
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/collections.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/collections.js
deleted file mode 100644
index 182f7a21..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/collections.js
+++ /dev/null
@@ -1,896 +0,0 @@
-(function() {
- var _ = typeof require == 'function' ? require('..') : window._;
-
- QUnit.module('Collections');
-
- QUnit.test('each', function(assert) {
- _.each([1, 2, 3], function(num, i) {
- assert.equal(num, i + 1, 'each iterators provide value and iteration count');
- });
-
- var answers = [];
- _.each([1, 2, 3], function(num){ answers.push(num * this.multiplier); }, {multiplier: 5});
- assert.deepEqual(answers, [5, 10, 15], 'context object property accessed');
-
- answers = [];
- _.each([1, 2, 3], function(num){ answers.push(num); });
- assert.deepEqual(answers, [1, 2, 3], 'can iterate a simple array');
-
- answers = [];
- var obj = {one: 1, two: 2, three: 3};
- obj.constructor.prototype.four = 4;
- _.each(obj, function(value, key){ answers.push(key); });
- assert.deepEqual(answers, ['one', 'two', 'three'], 'iterating over objects works, and ignores the object prototype.');
- delete obj.constructor.prototype.four;
-
- // ensure the each function is JITed
- _(1000).times(function() { _.each([], function(){}); });
- var count = 0;
- obj = {1: 'foo', 2: 'bar', 3: 'baz'};
- _.each(obj, function(){ count++; });
- assert.equal(count, 3, 'the fun should be called only 3 times');
-
- var answer = null;
- _.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; });
- assert.ok(answer, 'can reference the original collection from inside the iterator');
-
- answers = 0;
- _.each(null, function(){ ++answers; });
- assert.equal(answers, 0, 'handles a null properly');
-
- _.each(false, function(){});
-
- var a = [1, 2, 3];
- assert.strictEqual(_.each(a, function(){}), a);
- assert.strictEqual(_.each(null, function(){}), null);
- });
-
- QUnit.test('forEach', function(assert) {
- assert.strictEqual(_.forEach, _.each, 'is an alias for each');
- });
-
- QUnit.test('lookupIterator with contexts', function(assert) {
- _.each([true, false, 'yes', '', 0, 1, {}], function(context) {
- _.each([1], function() {
- assert.equal(this, context);
- }, context);
- });
- });
-
- QUnit.test('Iterating objects with sketchy length properties', function(assert) {
- var functions = [
- 'each', 'map', 'filter', 'find',
- 'some', 'every', 'max', 'min',
- 'groupBy', 'countBy', 'partition', 'indexBy'
- ];
- var reducers = ['reduce', 'reduceRight'];
-
- var tricks = [
- {length: '5'},
- {length: {valueOf: _.constant(5)}},
- {length: Math.pow(2, 53) + 1},
- {length: Math.pow(2, 53)},
- {length: null},
- {length: -2},
- {length: new Number(15)}
- ];
-
- assert.expect(tricks.length * (functions.length + reducers.length + 4));
-
- _.each(tricks, function(trick) {
- var length = trick.length;
- assert.strictEqual(_.size(trick), 1, 'size on obj with length: ' + length);
- assert.deepEqual(_.toArray(trick), [length], 'toArray on obj with length: ' + length);
- assert.deepEqual(_.shuffle(trick), [length], 'shuffle on obj with length: ' + length);
- assert.deepEqual(_.sample(trick), length, 'sample on obj with length: ' + length);
-
-
- _.each(functions, function(method) {
- _[method](trick, function(val, key) {
- assert.strictEqual(key, 'length', method + ': ran with length = ' + val);
- });
- });
-
- _.each(reducers, function(method) {
- assert.strictEqual(_[method](trick), trick.length, method);
- });
- });
- });
-
- QUnit.test('Resistant to collection length and properties changing while iterating', function(assert) {
-
- var collection = [
- 'each', 'map', 'filter', 'find',
- 'some', 'every', 'max', 'min', 'reject',
- 'groupBy', 'countBy', 'partition', 'indexBy',
- 'reduce', 'reduceRight'
- ];
- var array = [
- 'findIndex', 'findLastIndex'
- ];
- var object = [
- 'mapObject', 'findKey', 'pick', 'omit'
- ];
-
- _.each(collection.concat(array), function(method) {
- var sparseArray = [1, 2, 3];
- sparseArray.length = 100;
- var answers = 0;
- _[method](sparseArray, function(){
- ++answers;
- return method === 'every' ? true : null;
- }, {});
- assert.equal(answers, 100, method + ' enumerates [0, length)');
-
- var growingCollection = [1, 2, 3], count = 0;
- _[method](growingCollection, function() {
- if (count < 10) growingCollection.push(count++);
- return method === 'every' ? true : null;
- }, {});
- assert.equal(count, 3, method + ' is resistant to length changes');
- });
-
- _.each(collection.concat(object), function(method) {
- var changingObject = {0: 0, 1: 1}, count = 0;
- _[method](changingObject, function(val) {
- if (count < 10) changingObject[++count] = val + 1;
- return method === 'every' ? true : null;
- }, {});
-
- assert.equal(count, 2, method + ' is resistant to property changes');
- });
- });
-
- QUnit.test('map', function(assert) {
- var doubled = _.map([1, 2, 3], function(num){ return num * 2; });
- assert.deepEqual(doubled, [2, 4, 6], 'doubled numbers');
-
- var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier: 3});
- assert.deepEqual(tripled, [3, 6, 9], 'tripled numbers with context');
-
- doubled = _([1, 2, 3]).map(function(num){ return num * 2; });
- assert.deepEqual(doubled, [2, 4, 6], 'OO-style doubled numbers');
-
- var ids = _.map({length: 2, 0: {id: '1'}, 1: {id: '2'}}, function(n){
- return n.id;
- });
- assert.deepEqual(ids, ['1', '2'], 'Can use collection methods on Array-likes.');
-
- assert.deepEqual(_.map(null, _.noop), [], 'handles a null properly');
-
- assert.deepEqual(_.map([1], function() {
- return this.length;
- }, [5]), [1], 'called with context');
-
- // Passing a property name like _.pluck.
- var people = [{name: 'moe', age: 30}, {name: 'curly', age: 50}];
- assert.deepEqual(_.map(people, 'name'), ['moe', 'curly'], 'predicate string map to object properties');
- });
-
- QUnit.test('collect', function(assert) {
- assert.strictEqual(_.collect, _.map, 'is an alias for map');
- });
-
- QUnit.test('reduce', function(assert) {
- var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0);
- assert.equal(sum, 6, 'can sum up an array');
-
- var context = {multiplier: 3};
- sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num * this.multiplier; }, 0, context);
- assert.equal(sum, 18, 'can reduce with a context object');
-
- sum = _([1, 2, 3]).reduce(function(memo, num){ return memo + num; }, 0);
- assert.equal(sum, 6, 'OO-style reduce');
-
- sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; });
- assert.equal(sum, 6, 'default initial value');
-
- var prod = _.reduce([1, 2, 3, 4], function(memo, num){ return memo * num; });
- assert.equal(prod, 24, 'can reduce via multiplication');
-
- assert.ok(_.reduce(null, _.noop, 138) === 138, 'handles a null (with initial value) properly');
- assert.equal(_.reduce([], _.noop, void 0), void 0, 'undefined can be passed as a special case');
- assert.equal(_.reduce([_], _.noop), _, 'collection of length one with no initial value returns the first item');
- assert.equal(_.reduce([], _.noop), void 0, 'returns undefined when collection is empty and no initial value');
- });
-
- QUnit.test('foldl', function(assert) {
- assert.strictEqual(_.foldl, _.reduce, 'is an alias for reduce');
- });
-
- QUnit.test('inject', function(assert) {
- assert.strictEqual(_.inject, _.reduce, 'is an alias for reduce');
- });
-
- QUnit.test('reduceRight', function(assert) {
- var list = _.reduceRight(['foo', 'bar', 'baz'], function(memo, str){ return memo + str; }, '');
- assert.equal(list, 'bazbarfoo', 'can perform right folds');
-
- list = _.reduceRight(['foo', 'bar', 'baz'], function(memo, str){ return memo + str; });
- assert.equal(list, 'bazbarfoo', 'default initial value');
-
- var sum = _.reduceRight({a: 1, b: 2, c: 3}, function(memo, num){ return memo + num; });
- assert.equal(sum, 6, 'default initial value on object');
-
- assert.ok(_.reduceRight(null, _.noop, 138) === 138, 'handles a null (with initial value) properly');
- assert.equal(_.reduceRight([_], _.noop), _, 'collection of length one with no initial value returns the first item');
-
- assert.equal(_.reduceRight([], _.noop, void 0), void 0, 'undefined can be passed as a special case');
- assert.equal(_.reduceRight([], _.noop), void 0, 'returns undefined when collection is empty and no initial value');
-
- // Assert that the correct arguments are being passed.
-
- var args,
- init = {},
- object = {a: 1, b: 2},
- lastKey = _.keys(object).pop();
-
- var expected = lastKey === 'a'
- ? [init, 1, 'a', object]
- : [init, 2, 'b', object];
-
- _.reduceRight(object, function() {
- if (!args) args = _.toArray(arguments);
- }, init);
-
- assert.deepEqual(args, expected);
-
- // And again, with numeric keys.
-
- object = {2: 'a', 1: 'b'};
- lastKey = _.keys(object).pop();
- args = null;
-
- expected = lastKey === '2'
- ? [init, 'a', '2', object]
- : [init, 'b', '1', object];
-
- _.reduceRight(object, function() {
- if (!args) args = _.toArray(arguments);
- }, init);
-
- assert.deepEqual(args, expected);
- });
-
- QUnit.test('foldr', function(assert) {
- assert.strictEqual(_.foldr, _.reduceRight, 'is an alias for reduceRight');
- });
-
- QUnit.test('find', function(assert) {
- var array = [1, 2, 3, 4];
- assert.strictEqual(_.find(array, function(n) { return n > 2; }), 3, 'should return first found `value`');
- assert.strictEqual(_.find(array, function() { return false; }), void 0, 'should return `undefined` if `value` is not found');
-
- array.dontmatch = 55;
- assert.strictEqual(_.find(array, function(x) { return x === 55; }), void 0, 'iterates array-likes correctly');
-
- // Matching an object like _.findWhere.
- var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}, {a: 2, b: 4}];
- assert.deepEqual(_.find(list, {a: 1}), {a: 1, b: 2}, 'can be used as findWhere');
- assert.deepEqual(_.find(list, {b: 4}), {a: 1, b: 4});
- assert.ok(!_.find(list, {c: 1}), 'undefined when not found');
- assert.ok(!_.find([], {c: 1}), 'undefined when searching empty list');
-
- var result = _.find([1, 2, 3], function(num){ return num * 2 === 4; });
- assert.equal(result, 2, 'found the first "2" and broke the loop');
-
- var obj = {
- a: {x: 1, z: 3},
- b: {x: 2, z: 2},
- c: {x: 3, z: 4},
- d: {x: 4, z: 1}
- };
-
- assert.deepEqual(_.find(obj, {x: 2}), {x: 2, z: 2}, 'works on objects');
- assert.deepEqual(_.find(obj, {x: 2, z: 1}), void 0);
- assert.deepEqual(_.find(obj, function(x) {
- return x.x === 4;
- }), {x: 4, z: 1});
-
- _.findIndex([{a: 1}], function(a, key, o) {
- assert.equal(key, 0);
- assert.deepEqual(o, [{a: 1}]);
- assert.strictEqual(this, _, 'called with context');
- }, _);
- });
-
- QUnit.test('detect', function(assert) {
- assert.strictEqual(_.detect, _.find, 'is an alias for find');
- });
-
- QUnit.test('filter', function(assert) {
- var evenArray = [1, 2, 3, 4, 5, 6];
- var evenObject = {one: 1, two: 2, three: 3};
- var isEven = function(num){ return num % 2 === 0; };
-
- assert.deepEqual(_.filter(evenArray, isEven), [2, 4, 6]);
- assert.deepEqual(_.filter(evenObject, isEven), [2], 'can filter objects');
- assert.deepEqual(_.filter([{}, evenObject, []], 'two'), [evenObject], 'predicate string map to object properties');
-
- _.filter([1], function() {
- assert.equal(this, evenObject, 'given context');
- }, evenObject);
-
- // Can be used like _.where.
- var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
- assert.deepEqual(_.filter(list, {a: 1}), [{a: 1, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}]);
- assert.deepEqual(_.filter(list, {b: 2}), [{a: 1, b: 2}, {a: 2, b: 2}]);
- assert.deepEqual(_.filter(list, {}), list, 'Empty object accepts all items');
- assert.deepEqual(_(list).filter({}), list, 'OO-filter');
- });
-
- QUnit.test('select', function(assert) {
- assert.strictEqual(_.select, _.filter, 'is an alias for filter');
- });
-
- QUnit.test('reject', function(assert) {
- var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 === 0; });
- assert.deepEqual(odds, [1, 3, 5], 'rejected each even number');
-
- var context = 'obj';
-
- var evens = _.reject([1, 2, 3, 4, 5, 6], function(num){
- assert.equal(context, 'obj');
- return num % 2 !== 0;
- }, context);
- assert.deepEqual(evens, [2, 4, 6], 'rejected each odd number');
-
- assert.deepEqual(_.reject([odds, {one: 1, two: 2, three: 3}], 'two'), [odds], 'predicate string map to object properties');
-
- // Can be used like _.where.
- var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
- assert.deepEqual(_.reject(list, {a: 1}), [{a: 2, b: 2}]);
- assert.deepEqual(_.reject(list, {b: 2}), [{a: 1, b: 3}, {a: 1, b: 4}]);
- assert.deepEqual(_.reject(list, {}), [], 'Returns empty list given empty object');
- assert.deepEqual(_.reject(list, []), [], 'Returns empty list given empty array');
- });
-
- QUnit.test('every', function(assert) {
- assert.ok(_.every([], _.identity), 'the empty set');
- assert.ok(_.every([true, true, true], _.identity), 'every true values');
- assert.ok(!_.every([true, false, true], _.identity), 'one false value');
- assert.ok(_.every([0, 10, 28], function(num){ return num % 2 === 0; }), 'even numbers');
- assert.ok(!_.every([0, 11, 28], function(num){ return num % 2 === 0; }), 'an odd number');
- assert.ok(_.every([1], _.identity) === true, 'cast to boolean - true');
- assert.ok(_.every([0], _.identity) === false, 'cast to boolean - false');
- assert.ok(!_.every([void 0, void 0, void 0], _.identity), 'works with arrays of undefined');
-
- var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
- assert.ok(!_.every(list, {a: 1, b: 2}), 'Can be called with object');
- assert.ok(_.every(list, 'a'), 'String mapped to object property');
-
- list = [{a: 1, b: 2}, {a: 2, b: 2, c: true}];
- assert.ok(_.every(list, {b: 2}), 'Can be called with object');
- assert.ok(!_.every(list, 'c'), 'String mapped to object property');
-
- assert.ok(_.every({a: 1, b: 2, c: 3, d: 4}, _.isNumber), 'takes objects');
- assert.ok(!_.every({a: 1, b: 2, c: 3, d: 4}, _.isObject), 'takes objects');
- assert.ok(_.every(['a', 'b', 'c', 'd'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works');
- assert.ok(!_.every(['a', 'b', 'c', 'd', 'f'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works');
- });
-
- QUnit.test('all', function(assert) {
- assert.strictEqual(_.all, _.every, 'is an alias for every');
- });
-
- QUnit.test('some', function(assert) {
- assert.ok(!_.some([]), 'the empty set');
- assert.ok(!_.some([false, false, false]), 'all false values');
- assert.ok(_.some([false, false, true]), 'one true value');
- assert.ok(_.some([null, 0, 'yes', false]), 'a string');
- assert.ok(!_.some([null, 0, '', false]), 'falsy values');
- assert.ok(!_.some([1, 11, 29], function(num){ return num % 2 === 0; }), 'all odd numbers');
- assert.ok(_.some([1, 10, 29], function(num){ return num % 2 === 0; }), 'an even number');
- assert.ok(_.some([1], _.identity) === true, 'cast to boolean - true');
- assert.ok(_.some([0], _.identity) === false, 'cast to boolean - false');
- assert.ok(_.some([false, false, true]));
-
- var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
- assert.ok(!_.some(list, {a: 5, b: 2}), 'Can be called with object');
- assert.ok(_.some(list, 'a'), 'String mapped to object property');
-
- list = [{a: 1, b: 2}, {a: 2, b: 2, c: true}];
- assert.ok(_.some(list, {b: 2}), 'Can be called with object');
- assert.ok(!_.some(list, 'd'), 'String mapped to object property');
-
- assert.ok(_.some({a: '1', b: '2', c: '3', d: '4', e: 6}, _.isNumber), 'takes objects');
- assert.ok(!_.some({a: 1, b: 2, c: 3, d: 4}, _.isObject), 'takes objects');
- assert.ok(_.some(['a', 'b', 'c', 'd'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works');
- assert.ok(!_.some(['x', 'y', 'z'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works');
- });
-
- QUnit.test('any', function(assert) {
- assert.strictEqual(_.any, _.some, 'is an alias for some');
- });
-
- QUnit.test('includes', function(assert) {
- _.each([null, void 0, 0, 1, NaN, {}, []], function(val) {
- assert.strictEqual(_.includes(val, 'hasOwnProperty'), false);
- });
- assert.strictEqual(_.includes([1, 2, 3], 2), true, 'two is in the array');
- assert.ok(!_.includes([1, 3, 9], 2), 'two is not in the array');
-
- assert.strictEqual(_.includes([5, 4, 3, 2, 1], 5, true), true, 'doesn\'t delegate to binary search');
-
- assert.ok(_.includes({moe: 1, larry: 3, curly: 9}, 3) === true, '_.includes on objects checks their values');
- assert.ok(_([1, 2, 3]).includes(2), 'OO-style includes');
-
- var numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
- assert.strictEqual(_.includes(numbers, 1, 1), true, 'takes a fromIndex');
- assert.strictEqual(_.includes(numbers, 1, -1), false, 'takes a fromIndex');
- assert.strictEqual(_.includes(numbers, 1, -2), false, 'takes a fromIndex');
- assert.strictEqual(_.includes(numbers, 1, -3), true, 'takes a fromIndex');
- assert.strictEqual(_.includes(numbers, 1, 6), true, 'takes a fromIndex');
- assert.strictEqual(_.includes(numbers, 1, 7), false, 'takes a fromIndex');
-
- assert.ok(_.every([1, 2, 3], _.partial(_.includes, numbers)), 'fromIndex is guarded');
- });
-
- QUnit.test('include', function(assert) {
- assert.strictEqual(_.include, _.includes, 'is an alias for includes');
- });
-
- QUnit.test('contains', function(assert) {
- assert.strictEqual(_.contains, _.includes, 'is an alias for includes');
-
- });
-
- QUnit.test('includes with NaN', function(assert) {
- assert.strictEqual(_.includes([1, 2, NaN, NaN], NaN), true, 'Expected [1, 2, NaN] to contain NaN');
- assert.strictEqual(_.includes([1, 2, Infinity], NaN), false, 'Expected [1, 2, NaN] to contain NaN');
- });
-
- QUnit.test('includes with +- 0', function(assert) {
- _.each([-0, +0], function(val) {
- assert.strictEqual(_.includes([1, 2, val, val], val), true);
- assert.strictEqual(_.includes([1, 2, val, val], -val), true);
- assert.strictEqual(_.includes([-1, 1, 2], -val), false);
- });
- });
-
-
- QUnit.test('invoke', function(assert) {
- assert.expect(5);
- var list = [[5, 1, 7], [3, 2, 1]];
- var result = _.invoke(list, 'sort');
- assert.deepEqual(result[0], [1, 5, 7], 'first array sorted');
- assert.deepEqual(result[1], [1, 2, 3], 'second array sorted');
-
- _.invoke([{
- method: function() {
- assert.deepEqual(_.toArray(arguments), [1, 2, 3], 'called with arguments');
- }
- }], 'method', 1, 2, 3);
-
- assert.deepEqual(_.invoke([{a: null}, {}, {a: _.constant(1)}], 'a'), [null, void 0, 1], 'handles null & undefined');
-
- assert.raises(function() {
- _.invoke([{a: 1}], 'a');
- }, TypeError, 'throws for non-functions');
- });
-
- QUnit.test('invoke w/ function reference', function(assert) {
- var list = [[5, 1, 7], [3, 2, 1]];
- var result = _.invoke(list, Array.prototype.sort);
- assert.deepEqual(result[0], [1, 5, 7], 'first array sorted');
- assert.deepEqual(result[1], [1, 2, 3], 'second array sorted');
-
- assert.deepEqual(_.invoke([1, 2, 3], function(a) {
- return a + this;
- }, 5), [6, 7, 8], 'receives params from invoke');
- });
-
- // Relevant when using ClojureScript
- QUnit.test('invoke when strings have a call method', function(assert) {
- String.prototype.call = function() {
- return 42;
- };
- var list = [[5, 1, 7], [3, 2, 1]];
- var s = 'foo';
- assert.equal(s.call(), 42, 'call function exists');
- var result = _.invoke(list, 'sort');
- assert.deepEqual(result[0], [1, 5, 7], 'first array sorted');
- assert.deepEqual(result[1], [1, 2, 3], 'second array sorted');
- delete String.prototype.call;
- assert.equal(s.call, void 0, 'call function removed');
- });
-
- QUnit.test('pluck', function(assert) {
- var people = [{name: 'moe', age: 30}, {name: 'curly', age: 50}];
- assert.deepEqual(_.pluck(people, 'name'), ['moe', 'curly'], 'pulls names out of objects');
- assert.deepEqual(_.pluck(people, 'address'), [void 0, void 0], 'missing properties are returned as undefined');
- //compat: most flexible handling of edge cases
- assert.deepEqual(_.pluck([{'[object Object]': 1}], {}), [1]);
- });
-
- QUnit.test('where', function(assert) {
- var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
- var result = _.where(list, {a: 1});
- assert.equal(result.length, 3);
- assert.equal(result[result.length - 1].b, 4);
- result = _.where(list, {b: 2});
- assert.equal(result.length, 2);
- assert.equal(result[0].a, 1);
- result = _.where(list, {});
- assert.equal(result.length, list.length);
-
- function test() {}
- test.map = _.map;
- assert.deepEqual(_.where([_, {a: 1, b: 2}, _], test), [_, _], 'checks properties given function');
- });
-
- QUnit.test('findWhere', function(assert) {
- var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}, {a: 2, b: 4}];
- var result = _.findWhere(list, {a: 1});
- assert.deepEqual(result, {a: 1, b: 2});
- result = _.findWhere(list, {b: 4});
- assert.deepEqual(result, {a: 1, b: 4});
-
- result = _.findWhere(list, {c: 1});
- assert.ok(_.isUndefined(result), 'undefined when not found');
-
- result = _.findWhere([], {c: 1});
- assert.ok(_.isUndefined(result), 'undefined when searching empty list');
-
- function test() {}
- test.map = _.map;
- assert.equal(_.findWhere([_, {a: 1, b: 2}, _], test), _, 'checks properties given function');
-
- function TestClass() {
- this.y = 5;
- this.x = 'foo';
- }
- var expect = {c: 1, x: 'foo', y: 5};
- assert.deepEqual(_.findWhere([{y: 5, b: 6}, expect], new TestClass()), expect, 'uses class instance properties');
- });
-
- QUnit.test('max', function(assert) {
- assert.equal(-Infinity, _.max(null), 'can handle null/undefined');
- assert.equal(-Infinity, _.max(void 0), 'can handle null/undefined');
- assert.equal(-Infinity, _.max(null, _.identity), 'can handle null/undefined');
-
- assert.equal(3, _.max([1, 2, 3]), 'can perform a regular Math.max');
-
- var neg = _.max([1, 2, 3], function(num){ return -num; });
- assert.equal(neg, 1, 'can perform a computation-based max');
-
- assert.equal(-Infinity, _.max({}), 'Maximum value of an empty object');
- assert.equal(-Infinity, _.max([]), 'Maximum value of an empty array');
- assert.equal(_.max({a: 'a'}), -Infinity, 'Maximum value of a non-numeric collection');
-
- assert.equal(299999, _.max(_.range(1, 300000)), 'Maximum value of a too-big array');
-
- assert.equal(3, _.max([1, 2, 3, 'test']), 'Finds correct max in array starting with num and containing a NaN');
- assert.equal(3, _.max(['test', 1, 2, 3]), 'Finds correct max in array starting with NaN');
-
- assert.equal(3, _.max([1, 2, 3, null]), 'Finds correct max in array starting with num and containing a `null`');
- assert.equal(3, _.max([null, 1, 2, 3]), 'Finds correct max in array starting with a `null`');
-
- assert.equal(3, _.max([1, 2, 3, '']), 'Finds correct max in array starting with num and containing an empty string');
- assert.equal(3, _.max(['', 1, 2, 3]), 'Finds correct max in array starting with an empty string');
-
- assert.equal(3, _.max([1, 2, 3, false]), 'Finds correct max in array starting with num and containing a false');
- assert.equal(3, _.max([false, 1, 2, 3]), 'Finds correct max in array starting with a false');
-
- assert.equal(4, _.max([0, 1, 2, 3, 4]), 'Finds correct max in array containing a zero');
- assert.equal(0, _.max([-3, -2, -1, 0]), 'Finds correct max in array containing negative numbers');
-
- assert.deepEqual([3, 6], _.map([[1, 2, 3], [4, 5, 6]], _.max), 'Finds correct max in array when mapping through multiple arrays');
-
- var a = {x: -Infinity};
- var b = {x: -Infinity};
- var iterator = function(o){ return o.x; };
- assert.equal(_.max([a, b], iterator), a, 'Respects iterator return value of -Infinity');
-
- assert.deepEqual(_.max([{a: 1}, {a: 0, b: 3}, {a: 4}, {a: 2}], 'a'), {a: 4}, 'String keys use property iterator');
-
- assert.deepEqual(_.max([0, 2], function(c){ return c * this.x; }, {x: 1}), 2, 'Iterator context');
- assert.deepEqual(_.max([[1], [2, 3], [-1, 4], [5]], 0), [5], 'Lookup falsy iterator');
- assert.deepEqual(_.max([{0: 1}, {0: 2}, {0: -1}, {a: 1}], 0), {0: 2}, 'Lookup falsy iterator');
- });
-
- QUnit.test('min', function(assert) {
- assert.equal(Infinity, _.min(null), 'can handle null/undefined');
- assert.equal(Infinity, _.min(void 0), 'can handle null/undefined');
- assert.equal(Infinity, _.min(null, _.identity), 'can handle null/undefined');
-
- assert.equal(1, _.min([1, 2, 3]), 'can perform a regular Math.min');
-
- var neg = _.min([1, 2, 3], function(num){ return -num; });
- assert.equal(neg, 3, 'can perform a computation-based min');
-
- assert.equal(Infinity, _.min({}), 'Minimum value of an empty object');
- assert.equal(Infinity, _.min([]), 'Minimum value of an empty array');
- assert.equal(_.min({a: 'a'}), Infinity, 'Minimum value of a non-numeric collection');
-
- assert.deepEqual([1, 4], _.map([[1, 2, 3], [4, 5, 6]], _.min), 'Finds correct min in array when mapping through multiple arrays');
-
- var now = new Date(9999999999);
- var then = new Date(0);
- assert.equal(_.min([now, then]), then);
-
- assert.equal(1, _.min(_.range(1, 300000)), 'Minimum value of a too-big array');
-
- assert.equal(1, _.min([1, 2, 3, 'test']), 'Finds correct min in array starting with num and containing a NaN');
- assert.equal(1, _.min(['test', 1, 2, 3]), 'Finds correct min in array starting with NaN');
-
- assert.equal(1, _.min([1, 2, 3, null]), 'Finds correct min in array starting with num and containing a `null`');
- assert.equal(1, _.min([null, 1, 2, 3]), 'Finds correct min in array starting with a `null`');
-
- assert.equal(0, _.min([0, 1, 2, 3, 4]), 'Finds correct min in array containing a zero');
- assert.equal(-3, _.min([-3, -2, -1, 0]), 'Finds correct min in array containing negative numbers');
-
- var a = {x: Infinity};
- var b = {x: Infinity};
- var iterator = function(o){ return o.x; };
- assert.equal(_.min([a, b], iterator), a, 'Respects iterator return value of Infinity');
-
- assert.deepEqual(_.min([{a: 1}, {a: 0, b: 3}, {a: 4}, {a: 2}], 'a'), {a: 0, b: 3}, 'String keys use property iterator');
-
- assert.deepEqual(_.min([0, 2], function(c){ return c * this.x; }, {x: -1}), 2, 'Iterator context');
- assert.deepEqual(_.min([[1], [2, 3], [-1, 4], [5]], 0), [-1, 4], 'Lookup falsy iterator');
- assert.deepEqual(_.min([{0: 1}, {0: 2}, {0: -1}, {a: 1}], 0), {0: -1}, 'Lookup falsy iterator');
- });
-
- QUnit.test('sortBy', function(assert) {
- var people = [{name: 'curly', age: 50}, {name: 'moe', age: 30}];
- people = _.sortBy(people, function(person){ return person.age; });
- assert.deepEqual(_.pluck(people, 'name'), ['moe', 'curly'], 'stooges sorted by age');
-
- var list = [void 0, 4, 1, void 0, 3, 2];
- assert.deepEqual(_.sortBy(list, _.identity), [1, 2, 3, 4, void 0, void 0], 'sortBy with undefined values');
-
- list = ['one', 'two', 'three', 'four', 'five'];
- var sorted = _.sortBy(list, 'length');
- assert.deepEqual(sorted, ['one', 'two', 'four', 'five', 'three'], 'sorted by length');
-
- function Pair(x, y) {
- this.x = x;
- this.y = y;
- }
-
- var stableArray = [
- new Pair(1, 1), new Pair(1, 2),
- new Pair(1, 3), new Pair(1, 4),
- new Pair(1, 5), new Pair(1, 6),
- new Pair(2, 1), new Pair(2, 2),
- new Pair(2, 3), new Pair(2, 4),
- new Pair(2, 5), new Pair(2, 6),
- new Pair(void 0, 1), new Pair(void 0, 2),
- new Pair(void 0, 3), new Pair(void 0, 4),
- new Pair(void 0, 5), new Pair(void 0, 6)
- ];
-
- var stableObject = _.object('abcdefghijklmnopqr'.split(''), stableArray);
-
- var actual = _.sortBy(stableArray, function(pair) {
- return pair.x;
- });
-
- assert.deepEqual(actual, stableArray, 'sortBy should be stable for arrays');
- assert.deepEqual(_.sortBy(stableArray, 'x'), stableArray, 'sortBy accepts property string');
-
- actual = _.sortBy(stableObject, function(pair) {
- return pair.x;
- });
-
- assert.deepEqual(actual, stableArray, 'sortBy should be stable for objects');
-
- list = ['q', 'w', 'e', 'r', 't', 'y'];
- assert.deepEqual(_.sortBy(list), ['e', 'q', 'r', 't', 'w', 'y'], 'uses _.identity if iterator is not specified');
- });
-
- QUnit.test('groupBy', function(assert) {
- var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; });
- assert.ok('0' in parity && '1' in parity, 'created a group for each value');
- assert.deepEqual(parity[0], [2, 4, 6], 'put each even number in the right group');
-
- var list = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'];
- var grouped = _.groupBy(list, 'length');
- assert.deepEqual(grouped['3'], ['one', 'two', 'six', 'ten']);
- assert.deepEqual(grouped['4'], ['four', 'five', 'nine']);
- assert.deepEqual(grouped['5'], ['three', 'seven', 'eight']);
-
- var context = {};
- _.groupBy([{}], function(){ assert.ok(this === context); }, context);
-
- grouped = _.groupBy([4.2, 6.1, 6.4], function(num) {
- return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor';
- });
- assert.equal(grouped.constructor.length, 1);
- assert.equal(grouped.hasOwnProperty.length, 2);
-
- var array = [{}];
- _.groupBy(array, function(value, index, obj){ assert.ok(obj === array); });
-
- array = [1, 2, 1, 2, 3];
- grouped = _.groupBy(array);
- assert.equal(grouped['1'].length, 2);
- assert.equal(grouped['3'].length, 1);
-
- var matrix = [
- [1, 2],
- [1, 3],
- [2, 3]
- ];
- assert.deepEqual(_.groupBy(matrix, 0), {1: [[1, 2], [1, 3]], 2: [[2, 3]]});
- assert.deepEqual(_.groupBy(matrix, 1), {2: [[1, 2]], 3: [[1, 3], [2, 3]]});
- });
-
- QUnit.test('indexBy', function(assert) {
- var parity = _.indexBy([1, 2, 3, 4, 5], function(num){ return num % 2 === 0; });
- assert.equal(parity['true'], 4);
- assert.equal(parity['false'], 5);
-
- var list = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'];
- var grouped = _.indexBy(list, 'length');
- assert.equal(grouped['3'], 'ten');
- assert.equal(grouped['4'], 'nine');
- assert.equal(grouped['5'], 'eight');
-
- var array = [1, 2, 1, 2, 3];
- grouped = _.indexBy(array);
- assert.equal(grouped['1'], 1);
- assert.equal(grouped['2'], 2);
- assert.equal(grouped['3'], 3);
- });
-
- QUnit.test('countBy', function(assert) {
- var parity = _.countBy([1, 2, 3, 4, 5], function(num){ return num % 2 === 0; });
- assert.equal(parity['true'], 2);
- assert.equal(parity['false'], 3);
-
- var list = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'];
- var grouped = _.countBy(list, 'length');
- assert.equal(grouped['3'], 4);
- assert.equal(grouped['4'], 3);
- assert.equal(grouped['5'], 3);
-
- var context = {};
- _.countBy([{}], function(){ assert.ok(this === context); }, context);
-
- grouped = _.countBy([4.2, 6.1, 6.4], function(num) {
- return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor';
- });
- assert.equal(grouped.constructor, 1);
- assert.equal(grouped.hasOwnProperty, 2);
-
- var array = [{}];
- _.countBy(array, function(value, index, obj){ assert.ok(obj === array); });
-
- array = [1, 2, 1, 2, 3];
- grouped = _.countBy(array);
- assert.equal(grouped['1'], 2);
- assert.equal(grouped['3'], 1);
- });
-
- QUnit.test('shuffle', function(assert) {
- assert.deepEqual(_.shuffle([1]), [1], 'behaves correctly on size 1 arrays');
- var numbers = _.range(20);
- var shuffled = _.shuffle(numbers);
- assert.notDeepEqual(numbers, shuffled, 'does change the order'); // Chance of false negative: 1 in ~2.4*10^18
- assert.notStrictEqual(numbers, shuffled, 'original object is unmodified');
- assert.deepEqual(numbers, _.sortBy(shuffled), 'contains the same members before and after shuffle');
-
- shuffled = _.shuffle({a: 1, b: 2, c: 3, d: 4});
- assert.equal(shuffled.length, 4);
- assert.deepEqual(shuffled.sort(), [1, 2, 3, 4], 'works on objects');
- });
-
- QUnit.test('sample', function(assert) {
- assert.strictEqual(_.sample([1]), 1, 'behaves correctly when no second parameter is given');
- assert.deepEqual(_.sample([1, 2, 3], -2), [], 'behaves correctly on negative n');
- var numbers = _.range(10);
- var allSampled = _.sample(numbers, 10).sort();
- assert.deepEqual(allSampled, numbers, 'contains the same members before and after sample');
- allSampled = _.sample(numbers, 20).sort();
- assert.deepEqual(allSampled, numbers, 'also works when sampling more objects than are present');
- assert.ok(_.contains(numbers, _.sample(numbers)), 'sampling a single element returns something from the array');
- assert.strictEqual(_.sample([]), void 0, 'sampling empty array with no number returns undefined');
- assert.notStrictEqual(_.sample([], 5), [], 'sampling empty array with a number returns an empty array');
- assert.notStrictEqual(_.sample([1, 2, 3], 0), [], 'sampling an array with 0 picks returns an empty array');
- assert.deepEqual(_.sample([1, 2], -1), [], 'sampling a negative number of picks returns an empty array');
- assert.ok(_.contains([1, 2, 3], _.sample({a: 1, b: 2, c: 3})), 'sample one value from an object');
- var partialSample = _.sample(_.range(1000), 10);
- var partialSampleSorted = partialSample.sort();
- assert.notDeepEqual(partialSampleSorted, _.range(10), 'samples from the whole array, not just the beginning');
- });
-
- QUnit.test('toArray', function(assert) {
- assert.ok(!_.isArray(arguments), 'arguments object is not an array');
- assert.ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array');
- var a = [1, 2, 3];
- assert.ok(_.toArray(a) !== a, 'array is cloned');
- assert.deepEqual(_.toArray(a), [1, 2, 3], 'cloned array contains same elements');
-
- var numbers = _.toArray({one: 1, two: 2, three: 3});
- assert.deepEqual(numbers, [1, 2, 3], 'object flattened into array');
-
- var hearts = '\uD83D\uDC95';
- var pair = hearts.split('');
- var expected = [pair[0], hearts, '&', hearts, pair[1]];
- assert.deepEqual(_.toArray(expected.join('')), expected, 'maintains astral characters');
- assert.deepEqual(_.toArray(''), [], 'empty string into empty array');
-
- if (typeof document != 'undefined') {
- // test in IE < 9
- var actual;
- try {
- actual = _.toArray(document.childNodes);
- } catch (e) { /* ignored */ }
- assert.deepEqual(actual, _.map(document.childNodes, _.identity), 'works on NodeList');
- }
- });
-
- QUnit.test('size', function(assert) {
- assert.equal(_.size({one: 1, two: 2, three: 3}), 3, 'can compute the size of an object');
- assert.equal(_.size([1, 2, 3]), 3, 'can compute the size of an array');
- assert.equal(_.size({length: 3, 0: 0, 1: 0, 2: 0}), 3, 'can compute the size of Array-likes');
-
- var func = function() {
- return _.size(arguments);
- };
-
- assert.equal(func(1, 2, 3, 4), 4, 'can test the size of the arguments object');
-
- assert.equal(_.size('hello'), 5, 'can compute the size of a string literal');
- assert.equal(_.size(new String('hello')), 5, 'can compute the size of string object');
-
- assert.equal(_.size(null), 0, 'handles nulls');
- assert.equal(_.size(0), 0, 'handles numbers');
- });
-
- QUnit.test('partition', function(assert) {
- var list = [0, 1, 2, 3, 4, 5];
- assert.deepEqual(_.partition(list, function(x) { return x < 4; }), [[0, 1, 2, 3], [4, 5]], 'handles bool return values');
- assert.deepEqual(_.partition(list, function(x) { return x & 1; }), [[1, 3, 5], [0, 2, 4]], 'handles 0 and 1 return values');
- assert.deepEqual(_.partition(list, function(x) { return x - 3; }), [[0, 1, 2, 4, 5], [3]], 'handles other numeric return values');
- assert.deepEqual(_.partition(list, function(x) { return x > 1 ? null : true; }), [[0, 1], [2, 3, 4, 5]], 'handles null return values');
- assert.deepEqual(_.partition(list, function(x) { if (x < 2) return true; }), [[0, 1], [2, 3, 4, 5]], 'handles undefined return values');
- assert.deepEqual(_.partition({a: 1, b: 2, c: 3}, function(x) { return x > 1; }), [[2, 3], [1]], 'handles objects');
-
- assert.deepEqual(_.partition(list, function(x, index) { return index % 2; }), [[1, 3, 5], [0, 2, 4]], 'can reference the array index');
- assert.deepEqual(_.partition(list, function(x, index, arr) { return x === arr.length - 1; }), [[5], [0, 1, 2, 3, 4]], 'can reference the collection');
-
- // Default iterator
- assert.deepEqual(_.partition([1, false, true, '']), [[1, true], [false, '']], 'Default iterator');
- assert.deepEqual(_.partition([{x: 1}, {x: 0}, {x: 1}], 'x'), [[{x: 1}, {x: 1}], [{x: 0}]], 'Takes a string');
-
- // Context
- var predicate = function(x){ return x === this.x; };
- assert.deepEqual(_.partition([1, 2, 3], predicate, {x: 2}), [[2], [1, 3]], 'partition takes a context argument');
-
- assert.deepEqual(_.partition([{a: 1}, {b: 2}, {a: 1, b: 2}], {a: 1}), [[{a: 1}, {a: 1, b: 2}], [{b: 2}]], 'predicate can be object');
-
- var object = {a: 1};
- _.partition(object, function(val, key, obj) {
- assert.equal(val, 1);
- assert.equal(key, 'a');
- assert.equal(obj, object);
- assert.equal(this, predicate);
- }, predicate);
- });
-
- if (typeof document != 'undefined') {
- QUnit.test('Can use various collection methods on NodeLists', function(assert) {
- var parent = document.createElement('div');
- parent.innerHTML = '<span id=id1></span>textnode<span id=id2></span>';
-
- var elementChildren = _.filter(parent.childNodes, _.isElement);
- assert.equal(elementChildren.length, 2);
-
- assert.deepEqual(_.map(elementChildren, 'id'), ['id1', 'id2']);
- assert.deepEqual(_.map(parent.childNodes, 'nodeType'), [1, 3, 1]);
-
- assert.ok(!_.every(parent.childNodes, _.isElement));
- assert.ok(_.some(parent.childNodes, _.isElement));
-
- function compareNode(node) {
- return _.isElement(node) ? node.id.charAt(2) : void 0;
- }
- assert.equal(_.max(parent.childNodes, compareNode), _.last(parent.childNodes));
- assert.equal(_.min(parent.childNodes, compareNode), _.first(parent.childNodes));
- });
- }
-
-}());
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/cross-document.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/cross-document.js
deleted file mode 100644
index cb68a3d9..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/cross-document.js
+++ /dev/null
@@ -1,141 +0,0 @@
-(function() {
- if (typeof document == 'undefined') return;
-
- var _ = typeof require == 'function' ? require('..') : window._;
-
- QUnit.module('Cross Document');
- /* global iObject, iElement, iArguments, iFunction, iArray, iError, iString, iNumber, iBoolean, iDate, iRegExp, iNaN, iNull, iUndefined, ActiveXObject */
-
- // Setup remote variables for iFrame tests.
- var iframe = document.createElement('iframe');
- iframe.frameBorder = iframe.height = iframe.width = 0;
- document.body.appendChild(iframe);
- var iDoc = (iDoc = iframe.contentDocument || iframe.contentWindow).document || iDoc;
- iDoc.write(
- [
- '<script>',
- 'parent.iElement = document.createElement("div");',
- 'parent.iArguments = (function(){ return arguments; })(1, 2, 3);',
- 'parent.iArray = [1, 2, 3];',
- 'parent.iString = new String("hello");',
- 'parent.iNumber = new Number(100);',
- 'parent.iFunction = (function(){});',
- 'parent.iDate = new Date();',
- 'parent.iRegExp = /hi/;',
- 'parent.iNaN = NaN;',
- 'parent.iNull = null;',
- 'parent.iBoolean = new Boolean(false);',
- 'parent.iUndefined = undefined;',
- 'parent.iObject = {};',
- 'parent.iError = new Error();',
- '</script>'
- ].join('\n')
- );
- iDoc.close();
-
- QUnit.test('isEqual', function(assert) {
-
- assert.ok(!_.isEqual(iNumber, 101));
- assert.ok(_.isEqual(iNumber, 100));
-
- // Objects from another frame.
- assert.ok(_.isEqual({}, iObject), 'Objects with equivalent members created in different documents are equal');
-
- // Array from another frame.
- assert.ok(_.isEqual([1, 2, 3], iArray), 'Arrays with equivalent elements created in different documents are equal');
- });
-
- QUnit.test('isEmpty', function(assert) {
- assert.ok(!_([iNumber]).isEmpty(), '[1] is not empty');
- assert.ok(!_.isEmpty(iArray), '[] is empty');
- assert.ok(_.isEmpty(iObject), '{} is empty');
- });
-
- QUnit.test('isElement', function(assert) {
- assert.ok(!_.isElement('div'), 'strings are not dom elements');
- assert.ok(_.isElement(document.body), 'the body tag is a DOM element');
- assert.ok(_.isElement(iElement), 'even from another frame');
- });
-
- QUnit.test('isArguments', function(assert) {
- assert.ok(_.isArguments(iArguments), 'even from another frame');
- });
-
- QUnit.test('isObject', function(assert) {
- assert.ok(_.isObject(iElement), 'even from another frame');
- assert.ok(_.isObject(iFunction), 'even from another frame');
- });
-
- QUnit.test('isArray', function(assert) {
- assert.ok(_.isArray(iArray), 'even from another frame');
- });
-
- QUnit.test('isString', function(assert) {
- assert.ok(_.isString(iString), 'even from another frame');
- });
-
- QUnit.test('isNumber', function(assert) {
- assert.ok(_.isNumber(iNumber), 'even from another frame');
- });
-
- QUnit.test('isBoolean', function(assert) {
- assert.ok(_.isBoolean(iBoolean), 'even from another frame');
- });
-
- QUnit.test('isFunction', function(assert) {
- assert.ok(_.isFunction(iFunction), 'even from another frame');
- });
-
- QUnit.test('isDate', function(assert) {
- assert.ok(_.isDate(iDate), 'even from another frame');
- });
-
- QUnit.test('isRegExp', function(assert) {
- assert.ok(_.isRegExp(iRegExp), 'even from another frame');
- });
-
- QUnit.test('isNaN', function(assert) {
- assert.ok(_.isNaN(iNaN), 'even from another frame');
- });
-
- QUnit.test('isNull', function(assert) {
- assert.ok(_.isNull(iNull), 'even from another frame');
- });
-
- QUnit.test('isUndefined', function(assert) {
- assert.ok(_.isUndefined(iUndefined), 'even from another frame');
- });
-
- QUnit.test('isError', function(assert) {
- assert.ok(_.isError(iError), 'even from another frame');
- });
-
- if (typeof ActiveXObject != 'undefined') {
- QUnit.test('IE host objects', function(assert) {
- var xml = new ActiveXObject('Msxml2.DOMDocument.3.0');
- assert.ok(!_.isNumber(xml));
- assert.ok(!_.isBoolean(xml));
- assert.ok(!_.isNaN(xml));
- assert.ok(!_.isFunction(xml));
- assert.ok(!_.isNull(xml));
- assert.ok(!_.isUndefined(xml));
- });
-
- QUnit.test('#1621 IE 11 compat mode DOM elements are not functions', function(assert) {
- var fn = function() {};
- var xml = new ActiveXObject('Msxml2.DOMDocument.3.0');
- var div = document.createElement('div');
-
- // JIT the function
- var count = 200;
- while (count--) {
- _.isFunction(fn);
- }
-
- assert.equal(_.isFunction(xml), false);
- assert.equal(_.isFunction(div), false);
- assert.equal(_.isFunction(fn), true);
- });
- }
-
-}());
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/functions.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/functions.js
deleted file mode 100644
index f696bd64..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/functions.js
+++ /dev/null
@@ -1,728 +0,0 @@
-(function() {
- var _ = typeof require == 'function' ? require('..') : window._;
-
- QUnit.module('Functions');
- QUnit.config.asyncRetries = 3;
-
- QUnit.test('bind', function(assert) {
- var context = {name: 'moe'};
- var func = function(arg) { return 'name: ' + (this.name || arg); };
- var bound = _.bind(func, context);
- assert.equal(bound(), 'name: moe', 'can bind a function to a context');
-
- bound = _(func).bind(context);
- assert.equal(bound(), 'name: moe', 'can do OO-style binding');
-
- bound = _.bind(func, null, 'curly');
- var result = bound();
- // Work around a PhantomJS bug when applying a function with null|undefined.
- assert.ok(result === 'name: curly' || result === 'name: ' + window.name, 'can bind without specifying a context');
-
- func = function(salutation, name) { return salutation + ': ' + name; };
- func = _.bind(func, this, 'hello');
- assert.equal(func('moe'), 'hello: moe', 'the function was partially applied in advance');
-
- func = _.bind(func, this, 'curly');
- assert.equal(func(), 'hello: curly', 'the function was completely applied in advance');
-
- func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; };
- func = _.bind(func, this, 'hello', 'moe', 'curly');
- assert.equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments');
-
- func = function(ctx, message) { assert.equal(this, ctx, message); };
- _.bind(func, 0, 0, 'can bind a function to `0`')();
- _.bind(func, '', '', 'can bind a function to an empty string')();
- _.bind(func, false, false, 'can bind a function to `false`')();
-
- // These tests are only meaningful when using a browser without a native bind function
- // To test this with a modern browser, set underscore's nativeBind to undefined
- var F = function() { return this; };
- var boundf = _.bind(F, {hello: 'moe curly'});
- var Boundf = boundf; // make eslint happy.
- var newBoundf = new Boundf();
- assert.equal(newBoundf.hello, void 0, 'function should not be bound to the context, to comply with ECMAScript 5');
- assert.equal(boundf().hello, 'moe curly', "When called without the new operator, it's OK to be bound to the context");
- assert.ok(newBoundf instanceof F, 'a bound instance is an instance of the original function');
-
- assert.raises(function() { _.bind('notafunction'); }, TypeError, 'throws an error when binding to a non-function');
- });
-
- QUnit.test('partial', function(assert) {
- var obj = {name: 'moe'};
- var func = function() { return this.name + ' ' + _.toArray(arguments).join(' '); };
-
- obj.func = _.partial(func, 'a', 'b');
- assert.equal(obj.func('c', 'd'), 'moe a b c d', 'can partially apply');
-
- obj.func = _.partial(func, _, 'b', _, 'd');
- assert.equal(obj.func('a', 'c'), 'moe a b c d', 'can partially apply with placeholders');
-
- func = _.partial(function() { return arguments.length; }, _, 'b', _, 'd');
- assert.equal(func('a', 'c', 'e'), 5, 'accepts more arguments than the number of placeholders');
- assert.equal(func('a'), 4, 'accepts fewer arguments than the number of placeholders');
-
- func = _.partial(function() { return typeof arguments[2]; }, _, 'b', _, 'd');
- assert.equal(func('a'), 'undefined', 'unfilled placeholders are undefined');
-
- // passes context
- function MyWidget(name, options) {
- this.name = name;
- this.options = options;
- }
- MyWidget.prototype.get = function() {
- return this.name;
- };
- var MyWidgetWithCoolOpts = _.partial(MyWidget, _, {a: 1});
- var widget = new MyWidgetWithCoolOpts('foo');
- assert.ok(widget instanceof MyWidget, 'Can partially bind a constructor');
- assert.equal(widget.get(), 'foo', 'keeps prototype');
- assert.deepEqual(widget.options, {a: 1});
-
- _.partial.placeholder = obj;
- func = _.partial(function() { return arguments.length; }, obj, 'b', obj, 'd');
- assert.equal(func('a'), 4, 'allows the placeholder to be swapped out');
-
- _.partial.placeholder = {};
- func = _.partial(function() { return arguments.length; }, obj, 'b', obj, 'd');
- assert.equal(func('a'), 5, 'swapping the placeholder preserves previously bound arguments');
-
- _.partial.placeholder = _;
- });
-
- QUnit.test('bindAll', function(assert) {
- var curly = {name: 'curly'};
- var moe = {
- name: 'moe',
- getName: function() { return 'name: ' + this.name; },
- sayHi: function() { return 'hi: ' + this.name; }
- };
- curly.getName = moe.getName;
- _.bindAll(moe, 'getName', 'sayHi');
- curly.sayHi = moe.sayHi;
- assert.equal(curly.getName(), 'name: curly', 'unbound function is bound to current object');
- assert.equal(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object');
-
- curly = {name: 'curly'};
- moe = {
- name: 'moe',
- getName: function() { return 'name: ' + this.name; },
- sayHi: function() { return 'hi: ' + this.name; },
- sayLast: function() { return this.sayHi(_.last(arguments)); }
- };
-
- assert.raises(function() { _.bindAll(moe); }, Error, 'throws an error for bindAll with no functions named');
- assert.raises(function() { _.bindAll(moe, 'sayBye'); }, TypeError, 'throws an error for bindAll if the given key is undefined');
- assert.raises(function() { _.bindAll(moe, 'name'); }, TypeError, 'throws an error for bindAll if the given key is not a function');
-
- _.bindAll(moe, 'sayHi', 'sayLast');
- curly.sayHi = moe.sayHi;
- assert.equal(curly.sayHi(), 'hi: moe');
-
- var sayLast = moe.sayLast;
- assert.equal(sayLast(1, 2, 3, 4, 5, 6, 7, 'Tom'), 'hi: moe', 'createCallback works with any number of arguments');
-
- _.bindAll(moe, ['getName']);
- var getName = moe.getName;
- assert.equal(getName(), 'name: moe', 'flattens arguments into a single list');
- });
-
- QUnit.test('memoize', function(assert) {
- var fib = function(n) {
- return n < 2 ? n : fib(n - 1) + fib(n - 2);
- };
- assert.equal(fib(10), 55, 'a memoized version of fibonacci produces identical results');
- fib = _.memoize(fib); // Redefine `fib` for memoization
- assert.equal(fib(10), 55, 'a memoized version of fibonacci produces identical results');
-
- var o = function(str) {
- return str;
- };
- var fastO = _.memoize(o);
- assert.equal(o('toString'), 'toString', 'checks hasOwnProperty');
- assert.equal(fastO('toString'), 'toString', 'checks hasOwnProperty');
-
- // Expose the cache.
- var upper = _.memoize(function(s) {
- return s.toUpperCase();
- });
- assert.equal(upper('foo'), 'FOO');
- assert.equal(upper('bar'), 'BAR');
- assert.deepEqual(upper.cache, {foo: 'FOO', bar: 'BAR'});
- upper.cache = {foo: 'BAR', bar: 'FOO'};
- assert.equal(upper('foo'), 'BAR');
- assert.equal(upper('bar'), 'FOO');
-
- var hashed = _.memoize(function(key) {
- //https://github.com/jashkenas/underscore/pull/1679#discussion_r13736209
- assert.ok(/[a-z]+/.test(key), 'hasher doesn\'t change keys');
- return key;
- }, function(key) {
- return key.toUpperCase();
- });
- hashed('yep');
- assert.deepEqual(hashed.cache, {YEP: 'yep'}, 'takes a hasher');
-
- // Test that the hash function can be used to swizzle the key.
- var objCacher = _.memoize(function(value, key) {
- return {key: key, value: value};
- }, function(value, key) {
- return key;
- });
- var myObj = objCacher('a', 'alpha');
- var myObjAlias = objCacher('b', 'alpha');
- assert.notStrictEqual(myObj, void 0, 'object is created if second argument used as key');
- assert.strictEqual(myObj, myObjAlias, 'object is cached if second argument used as key');
- assert.strictEqual(myObj.value, 'a', 'object is not modified if second argument used as key');
- });
-
- QUnit.test('delay', function(assert) {
- assert.expect(2);
- var done = assert.async();
- var delayed = false;
- _.delay(function(){ delayed = true; }, 100);
- setTimeout(function(){ assert.ok(!delayed, "didn't delay the function quite yet"); }, 50);
- setTimeout(function(){ assert.ok(delayed, 'delayed the function'); done(); }, 150);
- });
-
- QUnit.test('defer', function(assert) {
- assert.expect(1);
- var done = assert.async();
- var deferred = false;
- _.defer(function(bool){ deferred = bool; }, true);
- _.delay(function(){ assert.ok(deferred, 'deferred the function'); done(); }, 50);
- });
-
- QUnit.test('throttle', function(assert) {
- assert.expect(2);
- var done = assert.async();
- var counter = 0;
- var incr = function(){ counter++; };
- var throttledIncr = _.throttle(incr, 32);
- throttledIncr(); throttledIncr();
-
- assert.equal(counter, 1, 'incr was called immediately');
- _.delay(function(){ assert.equal(counter, 2, 'incr was throttled'); done(); }, 64);
- });
-
- QUnit.test('throttle arguments', function(assert) {
- assert.expect(2);
- var done = assert.async();
- var value = 0;
- var update = function(val){ value = val; };
- var throttledUpdate = _.throttle(update, 32);
- throttledUpdate(1); throttledUpdate(2);
- _.delay(function(){ throttledUpdate(3); }, 64);
- assert.equal(value, 1, 'updated to latest value');
- _.delay(function(){ assert.equal(value, 3, 'updated to latest value'); done(); }, 96);
- });
-
- QUnit.test('throttle once', function(assert) {
- assert.expect(2);
- var done = assert.async();
- var counter = 0;
- var incr = function(){ return ++counter; };
- var throttledIncr = _.throttle(incr, 32);
- var result = throttledIncr();
- _.delay(function(){
- assert.equal(result, 1, 'throttled functions return their value');
- assert.equal(counter, 1, 'incr was called once'); done();
- }, 64);
- });
-
- QUnit.test('throttle twice', function(assert) {
- assert.expect(1);
- var done = assert.async();
- var counter = 0;
- var incr = function(){ counter++; };
- var throttledIncr = _.throttle(incr, 32);
- throttledIncr(); throttledIncr();
- _.delay(function(){ assert.equal(counter, 2, 'incr was called twice'); done(); }, 64);
- });
-
- QUnit.test('more throttling', function(assert) {
- assert.expect(3);
- var done = assert.async();
- var counter = 0;
- var incr = function(){ counter++; };
- var throttledIncr = _.throttle(incr, 30);
- throttledIncr(); throttledIncr();
- assert.equal(counter, 1);
- _.delay(function(){
- assert.equal(counter, 2);
- throttledIncr();
- assert.equal(counter, 3);
- done();
- }, 85);
- });
-
- QUnit.test('throttle repeatedly with results', function(assert) {
- assert.expect(6);
- var done = assert.async();
- var counter = 0;
- var incr = function(){ return ++counter; };
- var throttledIncr = _.throttle(incr, 100);
- var results = [];
- var saveResult = function() { results.push(throttledIncr()); };
- saveResult(); saveResult();
- _.delay(saveResult, 50);
- _.delay(saveResult, 150);
- _.delay(saveResult, 160);
- _.delay(saveResult, 230);
- _.delay(function() {
- assert.equal(results[0], 1, 'incr was called once');
- assert.equal(results[1], 1, 'incr was throttled');
- assert.equal(results[2], 1, 'incr was throttled');
- assert.equal(results[3], 2, 'incr was called twice');
- assert.equal(results[4], 2, 'incr was throttled');
- assert.equal(results[5], 3, 'incr was called trailing');
- done();
- }, 300);
- });
-
- QUnit.test('throttle triggers trailing call when invoked repeatedly', function(assert) {
- assert.expect(2);
- var done = assert.async();
- var counter = 0;
- var limit = 48;
- var incr = function(){ counter++; };
- var throttledIncr = _.throttle(incr, 32);
-
- var stamp = new Date;
- while (new Date - stamp < limit) {
- throttledIncr();
- }
- var lastCount = counter;
- assert.ok(counter > 1);
-
- _.delay(function() {
- assert.ok(counter > lastCount);
- done();
- }, 96);
- });
-
- QUnit.test('throttle does not trigger leading call when leading is set to false', function(assert) {
- assert.expect(2);
- var done = assert.async();
- var counter = 0;
- var incr = function(){ counter++; };
- var throttledIncr = _.throttle(incr, 60, {leading: false});
-
- throttledIncr(); throttledIncr();
- assert.equal(counter, 0);
-
- _.delay(function() {
- assert.equal(counter, 1);
- done();
- }, 96);
- });
-
- QUnit.test('more throttle does not trigger leading call when leading is set to false', function(assert) {
- assert.expect(3);
- var done = assert.async();
- var counter = 0;
- var incr = function(){ counter++; };
- var throttledIncr = _.throttle(incr, 100, {leading: false});
-
- throttledIncr();
- _.delay(throttledIncr, 50);
- _.delay(throttledIncr, 60);
- _.delay(throttledIncr, 200);
- assert.equal(counter, 0);
-
- _.delay(function() {
- assert.equal(counter, 1);
- }, 250);
-
- _.delay(function() {
- assert.equal(counter, 2);
- done();
- }, 350);
- });
-
- QUnit.test('one more throttle with leading: false test', function(assert) {
- assert.expect(2);
- var done = assert.async();
- var counter = 0;
- var incr = function(){ counter++; };
- var throttledIncr = _.throttle(incr, 100, {leading: false});
-
- var time = new Date;
- while (new Date - time < 350) throttledIncr();
- assert.ok(counter <= 3);
-
- _.delay(function() {
- assert.ok(counter <= 4);
- done();
- }, 200);
- });
-
- QUnit.test('throttle does not trigger trailing call when trailing is set to false', function(assert) {
- assert.expect(4);
- var done = assert.async();
- var counter = 0;
- var incr = function(){ counter++; };
- var throttledIncr = _.throttle(incr, 60, {trailing: false});
-
- throttledIncr(); throttledIncr(); throttledIncr();
- assert.equal(counter, 1);
-
- _.delay(function() {
- assert.equal(counter, 1);
-
- throttledIncr(); throttledIncr();
- assert.equal(counter, 2);
-
- _.delay(function() {
- assert.equal(counter, 2);
- done();
- }, 96);
- }, 96);
- });
-
- QUnit.test('throttle continues to function after system time is set backwards', function(assert) {
- assert.expect(2);
- var done = assert.async();
- var counter = 0;
- var incr = function(){ counter++; };
- var throttledIncr = _.throttle(incr, 100);
- var origNowFunc = _.now;
-
- throttledIncr();
- assert.equal(counter, 1);
- _.now = function() {
- return new Date(2013, 0, 1, 1, 1, 1);
- };
-
- _.delay(function() {
- throttledIncr();
- assert.equal(counter, 2);
- done();
- _.now = origNowFunc;
- }, 200);
- });
-
- QUnit.test('throttle re-entrant', function(assert) {
- assert.expect(2);
- var done = assert.async();
- var sequence = [
- ['b1', 'b2'],
- ['c1', 'c2']
- ];
- var value = '';
- var throttledAppend;
- var append = function(arg){
- value += this + arg;
- var args = sequence.pop();
- if (args) {
- throttledAppend.call(args[0], args[1]);
- }
- };
- throttledAppend = _.throttle(append, 32);
- throttledAppend.call('a1', 'a2');
- assert.equal(value, 'a1a2');
- _.delay(function(){
- assert.equal(value, 'a1a2c1c2b1b2', 'append was throttled successfully');
- done();
- }, 100);
- });
-
- QUnit.test('throttle cancel', function(assert) {
- var done = assert.async();
- var counter = 0;
- var incr = function(){ counter++; };
- var throttledIncr = _.throttle(incr, 32);
- throttledIncr();
- throttledIncr.cancel();
- throttledIncr();
- throttledIncr();
-
- assert.equal(counter, 2, 'incr was called immediately');
- _.delay(function(){ assert.equal(counter, 3, 'incr was throttled'); done(); }, 64);
- });
-
- QUnit.test('throttle cancel with leading: false', function(assert) {
- var done = assert.async();
- var counter = 0;
- var incr = function(){ counter++; };
- var throttledIncr = _.throttle(incr, 32, {leading: false});
- throttledIncr();
- throttledIncr.cancel();
-
- assert.equal(counter, 0, 'incr was throttled');
- _.delay(function(){ assert.equal(counter, 0, 'incr was throttled'); done(); }, 64);
- });
-
- QUnit.test('debounce', function(assert) {
- assert.expect(1);
- var done = assert.async();
- var counter = 0;
- var incr = function(){ counter++; };
- var debouncedIncr = _.debounce(incr, 32);
- debouncedIncr(); debouncedIncr();
- _.delay(debouncedIncr, 16);
- _.delay(function(){ assert.equal(counter, 1, 'incr was debounced'); done(); }, 96);
- });
-
- QUnit.test('debounce cancel', function(assert) {
- assert.expect(1);
- var done = assert.async();
- var counter = 0;
- var incr = function(){ counter++; };
- var debouncedIncr = _.debounce(incr, 32);
- debouncedIncr();
- debouncedIncr.cancel();
- _.delay(function(){ assert.equal(counter, 0, 'incr was not called'); done(); }, 96);
- });
-
- QUnit.test('debounce asap', function(assert) {
- assert.expect(6);
- var done = assert.async();
- var a, b, c;
- var counter = 0;
- var incr = function(){ return ++counter; };
- var debouncedIncr = _.debounce(incr, 64, true);
- a = debouncedIncr();
- b = debouncedIncr();
- assert.equal(a, 1);
- assert.equal(b, 1);
- assert.equal(counter, 1, 'incr was called immediately');
- _.delay(debouncedIncr, 16);
- _.delay(debouncedIncr, 32);
- _.delay(debouncedIncr, 48);
- _.delay(function(){
- assert.equal(counter, 1, 'incr was debounced');
- c = debouncedIncr();
- assert.equal(c, 2);
- assert.equal(counter, 2, 'incr was called again');
- done();
- }, 128);
- });
-
- QUnit.test('debounce asap cancel', function(assert) {
- assert.expect(4);
- var done = assert.async();
- var a, b;
- var counter = 0;
- var incr = function(){ return ++counter; };
- var debouncedIncr = _.debounce(incr, 64, true);
- a = debouncedIncr();
- debouncedIncr.cancel();
- b = debouncedIncr();
- assert.equal(a, 1);
- assert.equal(b, 2);
- assert.equal(counter, 2, 'incr was called immediately');
- _.delay(debouncedIncr, 16);
- _.delay(debouncedIncr, 32);
- _.delay(debouncedIncr, 48);
- _.delay(function(){ assert.equal(counter, 2, 'incr was debounced'); done(); }, 128);
- });
-
- QUnit.test('debounce asap recursively', function(assert) {
- assert.expect(2);
- var done = assert.async();
- var counter = 0;
- var debouncedIncr = _.debounce(function(){
- counter++;
- if (counter < 10) debouncedIncr();
- }, 32, true);
- debouncedIncr();
- assert.equal(counter, 1, 'incr was called immediately');
- _.delay(function(){ assert.equal(counter, 1, 'incr was debounced'); done(); }, 96);
- });
-
- QUnit.test('debounce after system time is set backwards', function(assert) {
- assert.expect(2);
- var done = assert.async();
- var counter = 0;
- var origNowFunc = _.now;
- var debouncedIncr = _.debounce(function(){
- counter++;
- }, 100, true);
-
- debouncedIncr();
- assert.equal(counter, 1, 'incr was called immediately');
-
- _.now = function() {
- return new Date(2013, 0, 1, 1, 1, 1);
- };
-
- _.delay(function() {
- debouncedIncr();
- assert.equal(counter, 2, 'incr was debounced successfully');
- done();
- _.now = origNowFunc;
- }, 200);
- });
-
- QUnit.test('debounce re-entrant', function(assert) {
- assert.expect(2);
- var done = assert.async();
- var sequence = [
- ['b1', 'b2']
- ];
- var value = '';
- var debouncedAppend;
- var append = function(arg){
- value += this + arg;
- var args = sequence.pop();
- if (args) {
- debouncedAppend.call(args[0], args[1]);
- }
- };
- debouncedAppend = _.debounce(append, 32);
- debouncedAppend.call('a1', 'a2');
- assert.equal(value, '');
- _.delay(function(){
- assert.equal(value, 'a1a2b1b2', 'append was debounced successfully');
- done();
- }, 100);
- });
-
- QUnit.test('once', function(assert) {
- var num = 0;
- var increment = _.once(function(){ return ++num; });
- increment();
- increment();
- assert.equal(num, 1);
-
- assert.equal(increment(), 1, 'stores a memo to the last value');
- });
-
- QUnit.test('Recursive onced function.', function(assert) {
- assert.expect(1);
- var f = _.once(function(){
- assert.ok(true);
- f();
- });
- f();
- });
-
- QUnit.test('wrap', function(assert) {
- var greet = function(name){ return 'hi: ' + name; };
- var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); });
- assert.equal(backwards('moe'), 'hi: moe eom', 'wrapped the salutation function');
-
- var inner = function(){ return 'Hello '; };
- var obj = {name: 'Moe'};
- obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; });
- assert.equal(obj.hi(), 'Hello Moe');
-
- var noop = function(){};
- var wrapped = _.wrap(noop, function(){ return Array.prototype.slice.call(arguments, 0); });
- var ret = wrapped(['whats', 'your'], 'vector', 'victor');
- assert.deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']);
- });
-
- QUnit.test('negate', function(assert) {
- var isOdd = function(n){ return n & 1; };
- assert.equal(_.negate(isOdd)(2), true, 'should return the complement of the given function');
- assert.equal(_.negate(isOdd)(3), false, 'should return the complement of the given function');
- });
-
- QUnit.test('compose', function(assert) {
- var greet = function(name){ return 'hi: ' + name; };
- var exclaim = function(sentence){ return sentence + '!'; };
- var composed = _.compose(exclaim, greet);
- assert.equal(composed('moe'), 'hi: moe!', 'can compose a function that takes another');
-
- composed = _.compose(greet, exclaim);
- assert.equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative');
-
- // f(g(h(x, y, z)))
- function h(x, y, z) {
- assert.equal(arguments.length, 3, 'First function called with multiple args');
- return z * y;
- }
- function g(x) {
- assert.equal(arguments.length, 1, 'Composed function is called with 1 argument');
- return x;
- }
- function f(x) {
- assert.equal(arguments.length, 1, 'Composed function is called with 1 argument');
- return x * 2;
- }
- composed = _.compose(f, g, h);
- assert.equal(composed(1, 2, 3), 12);
- });
-
- QUnit.test('after', function(assert) {
- var testAfter = function(afterAmount, timesCalled) {
- var afterCalled = 0;
- var after = _.after(afterAmount, function() {
- afterCalled++;
- });
- while (timesCalled--) after();
- return afterCalled;
- };
-
- assert.equal(testAfter(5, 5), 1, 'after(N) should fire after being called N times');
- assert.equal(testAfter(5, 4), 0, 'after(N) should not fire unless called N times');
- assert.equal(testAfter(0, 0), 0, 'after(0) should not fire immediately');
- assert.equal(testAfter(0, 1), 1, 'after(0) should fire when first invoked');
- });
-
- QUnit.test('before', function(assert) {
- var testBefore = function(beforeAmount, timesCalled) {
- var beforeCalled = 0;
- var before = _.before(beforeAmount, function() { beforeCalled++; });
- while (timesCalled--) before();
- return beforeCalled;
- };
-
- assert.equal(testBefore(5, 5), 4, 'before(N) should not fire after being called N times');
- assert.equal(testBefore(5, 4), 4, 'before(N) should fire before being called N times');
- assert.equal(testBefore(0, 0), 0, 'before(0) should not fire immediately');
- assert.equal(testBefore(0, 1), 0, 'before(0) should not fire when first invoked');
-
- var context = {num: 0};
- var increment = _.before(3, function(){ return ++this.num; });
- _.times(10, increment, context);
- assert.equal(increment(), 2, 'stores a memo to the last value');
- assert.equal(context.num, 2, 'provides context');
- });
-
- QUnit.test('iteratee', function(assert) {
- var identity = _.iteratee();
- assert.equal(identity, _.identity, '_.iteratee is exposed as an external function.');
-
- function fn() {
- return arguments;
- }
- _.each([_.iteratee(fn), _.iteratee(fn, {})], function(cb) {
- assert.equal(cb().length, 0);
- assert.deepEqual(_.toArray(cb(1, 2, 3)), _.range(1, 4));
- assert.deepEqual(_.toArray(cb(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), _.range(1, 11));
- });
-
- });
-
- QUnit.test('restArgs', function(assert) {
- assert.expect(10);
- _.restArgs(function(a, args) {
- assert.strictEqual(a, 1);
- assert.deepEqual(args, [2, 3], 'collects rest arguments into an array');
- })(1, 2, 3);
-
- _.restArgs(function(a, args) {
- assert.strictEqual(a, void 0);
- assert.deepEqual(args, [], 'passes empty array if there are not enough arguments');
- })();
-
- _.restArgs(function(a, b, c, args) {
- assert.strictEqual(arguments.length, 4);
- assert.deepEqual(args, [4, 5], 'works on functions with many named parameters');
- })(1, 2, 3, 4, 5);
-
- var obj = {};
- _.restArgs(function() {
- assert.strictEqual(this, obj, 'invokes function with this context');
- }).call(obj);
-
- _.restArgs(function(array, iteratee, context) {
- assert.deepEqual(array, [1, 2, 3, 4], 'startIndex can be used manually specify index of rest parameter');
- assert.strictEqual(iteratee, void 0);
- assert.strictEqual(context, void 0);
- }, 0)(1, 2, 3, 4);
- });
-
-}());
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/objects.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/objects.js
deleted file mode 100644
index fa1d9e3e..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/objects.js
+++ /dev/null
@@ -1,1102 +0,0 @@
-(function() {
- var _ = typeof require == 'function' ? require('..') : window._;
-
- QUnit.module('Objects');
-
- var testElement = typeof document === 'object' ? document.createElement('div') : void 0;
-
- QUnit.test('keys', function(assert) {
- assert.deepEqual(_.keys({one: 1, two: 2}), ['one', 'two'], 'can extract the keys from an object');
- // the test above is not safe because it relies on for-in enumeration order
- var a = []; a[1] = 0;
- assert.deepEqual(_.keys(a), ['1'], 'is not fooled by sparse arrays; see issue #95');
- assert.deepEqual(_.keys(null), []);
- assert.deepEqual(_.keys(void 0), []);
- assert.deepEqual(_.keys(1), []);
- assert.deepEqual(_.keys('a'), []);
- assert.deepEqual(_.keys(true), []);
-
- // keys that may be missed if the implementation isn't careful
- var trouble = {
- constructor: Object,
- valueOf: _.noop,
- hasOwnProperty: null,
- toString: 5,
- toLocaleString: void 0,
- propertyIsEnumerable: /a/,
- isPrototypeOf: this,
- __defineGetter__: Boolean,
- __defineSetter__: {},
- __lookupSetter__: false,
- __lookupGetter__: []
- };
- var troubleKeys = ['constructor', 'valueOf', 'hasOwnProperty', 'toString', 'toLocaleString', 'propertyIsEnumerable',
- 'isPrototypeOf', '__defineGetter__', '__defineSetter__', '__lookupSetter__', '__lookupGetter__'].sort();
- assert.deepEqual(_.keys(trouble).sort(), troubleKeys, 'matches non-enumerable properties');
- });
-
- QUnit.test('allKeys', function(assert) {
- assert.deepEqual(_.allKeys({one: 1, two: 2}), ['one', 'two'], 'can extract the allKeys from an object');
- // the test above is not safe because it relies on for-in enumeration order
- var a = []; a[1] = 0;
- assert.deepEqual(_.allKeys(a), ['1'], 'is not fooled by sparse arrays; see issue #95');
-
- a.a = a;
- assert.deepEqual(_.allKeys(a), ['1', 'a'], 'is not fooled by sparse arrays with additional properties');
-
- _.each([null, void 0, 1, 'a', true, NaN, {}, [], new Number(5), new Date(0)], function(val) {
- assert.deepEqual(_.allKeys(val), []);
- });
-
- // allKeys that may be missed if the implementation isn't careful
- var trouble = {
- constructor: Object,
- valueOf: _.noop,
- hasOwnProperty: null,
- toString: 5,
- toLocaleString: void 0,
- propertyIsEnumerable: /a/,
- isPrototypeOf: this
- };
- var troubleKeys = ['constructor', 'valueOf', 'hasOwnProperty', 'toString', 'toLocaleString', 'propertyIsEnumerable',
- 'isPrototypeOf'].sort();
- assert.deepEqual(_.allKeys(trouble).sort(), troubleKeys, 'matches non-enumerable properties');
-
- function A() {}
- A.prototype.foo = 'foo';
- var b = new A();
- b.bar = 'bar';
- assert.deepEqual(_.allKeys(b).sort(), ['bar', 'foo'], 'should include inherited keys');
-
- function y() {}
- y.x = 'z';
- assert.deepEqual(_.allKeys(y), ['x'], 'should get keys from constructor');
- });
-
- QUnit.test('values', function(assert) {
- assert.deepEqual(_.values({one: 1, two: 2}), [1, 2], 'can extract the values from an object');
- assert.deepEqual(_.values({one: 1, two: 2, length: 3}), [1, 2, 3], '... even when one of them is "length"');
- });
-
- QUnit.test('pairs', function(assert) {
- assert.deepEqual(_.pairs({one: 1, two: 2}), [['one', 1], ['two', 2]], 'can convert an object into pairs');
- assert.deepEqual(_.pairs({one: 1, two: 2, length: 3}), [['one', 1], ['two', 2], ['length', 3]], '... even when one of them is "length"');
- });
-
- QUnit.test('invert', function(assert) {
- var obj = {first: 'Moe', second: 'Larry', third: 'Curly'};
- assert.deepEqual(_.keys(_.invert(obj)), ['Moe', 'Larry', 'Curly'], 'can invert an object');
- assert.deepEqual(_.invert(_.invert(obj)), obj, 'two inverts gets you back where you started');
-
- obj = {length: 3};
- assert.equal(_.invert(obj)['3'], 'length', 'can invert an object with "length"');
- });
-
- QUnit.test('functions', function(assert) {
- var obj = {a: 'dash', b: _.map, c: /yo/, d: _.reduce};
- assert.deepEqual(['b', 'd'], _.functions(obj), 'can grab the function names of any passed-in object');
-
- var Animal = function(){};
- Animal.prototype.run = function(){};
- assert.deepEqual(_.functions(new Animal), ['run'], 'also looks up functions on the prototype');
- });
-
- QUnit.test('methods', function(assert) {
- assert.strictEqual(_.methods, _.functions, 'is an alias for functions');
- });
-
- QUnit.test('extend', function(assert) {
- var result;
- assert.equal(_.extend({}, {a: 'b'}).a, 'b', 'can extend an object with the attributes of another');
- assert.equal(_.extend({a: 'x'}, {a: 'b'}).a, 'b', 'properties in source override destination');
- assert.equal(_.extend({x: 'x'}, {a: 'b'}).x, 'x', "properties not in source don't get overriden");
- result = _.extend({x: 'x'}, {a: 'a'}, {b: 'b'});
- assert.deepEqual(result, {x: 'x', a: 'a', b: 'b'}, 'can extend from multiple source objects');
- result = _.extend({x: 'x'}, {a: 'a', x: 2}, {a: 'b'});
- assert.deepEqual(result, {x: 2, a: 'b'}, 'extending from multiple source objects last property trumps');
- result = _.extend({}, {a: void 0, b: null});
- assert.deepEqual(_.keys(result), ['a', 'b'], 'extend copies undefined values');
-
- var F = function() {};
- F.prototype = {a: 'b'};
- var subObj = new F();
- subObj.c = 'd';
- assert.deepEqual(_.extend({}, subObj), {a: 'b', c: 'd'}, 'extend copies all properties from source');
- _.extend(subObj, {});
- assert.ok(!subObj.hasOwnProperty('a'), "extend does not convert destination object's 'in' properties to 'own' properties");
-
- try {
- result = {};
- _.extend(result, null, void 0, {a: 1});
- } catch (e) { /* ignored */ }
-
- assert.equal(result.a, 1, 'should not error on `null` or `undefined` sources');
-
- assert.strictEqual(_.extend(null, {a: 1}), null, 'extending null results in null');
- assert.strictEqual(_.extend(void 0, {a: 1}), void 0, 'extending undefined results in undefined');
- });
-
- QUnit.test('extendOwn', function(assert) {
- var result;
- assert.equal(_.extendOwn({}, {a: 'b'}).a, 'b', 'can extend an object with the attributes of another');
- assert.equal(_.extendOwn({a: 'x'}, {a: 'b'}).a, 'b', 'properties in source override destination');
- assert.equal(_.extendOwn({x: 'x'}, {a: 'b'}).x, 'x', "properties not in source don't get overriden");
- result = _.extendOwn({x: 'x'}, {a: 'a'}, {b: 'b'});
- assert.deepEqual(result, {x: 'x', a: 'a', b: 'b'}, 'can extend from multiple source objects');
- result = _.extendOwn({x: 'x'}, {a: 'a', x: 2}, {a: 'b'});
- assert.deepEqual(result, {x: 2, a: 'b'}, 'extending from multiple source objects last property trumps');
- assert.deepEqual(_.extendOwn({}, {a: void 0, b: null}), {a: void 0, b: null}, 'copies undefined values');
-
- var F = function() {};
- F.prototype = {a: 'b'};
- var subObj = new F();
- subObj.c = 'd';
- assert.deepEqual(_.extendOwn({}, subObj), {c: 'd'}, 'copies own properties from source');
-
- result = {};
- assert.deepEqual(_.extendOwn(result, null, void 0, {a: 1}), {a: 1}, 'should not error on `null` or `undefined` sources');
-
- _.each(['a', 5, null, false], function(val) {
- assert.strictEqual(_.extendOwn(val, {a: 1}), val, 'extending non-objects results in returning the non-object value');
- });
-
- assert.strictEqual(_.extendOwn(void 0, {a: 1}), void 0, 'extending undefined results in undefined');
-
- result = _.extendOwn({a: 1, 0: 2, 1: '5', length: 6}, {0: 1, 1: 2, length: 2});
- assert.deepEqual(result, {a: 1, 0: 1, 1: 2, length: 2}, 'should treat array-like objects like normal objects');
- });
-
- QUnit.test('assign', function(assert) {
- assert.strictEqual(_.assign, _.extendOwn, 'is an alias for extendOwn');
- });
-
- QUnit.test('pick', function(assert) {
- var result;
- result = _.pick({a: 1, b: 2, c: 3}, 'a', 'c');
- assert.deepEqual(result, {a: 1, c: 3}, 'can restrict properties to those named');
- result = _.pick({a: 1, b: 2, c: 3}, ['b', 'c']);
- assert.deepEqual(result, {b: 2, c: 3}, 'can restrict properties to those named in an array');
- result = _.pick({a: 1, b: 2, c: 3}, ['a'], 'b');
- assert.deepEqual(result, {a: 1, b: 2}, 'can restrict properties to those named in mixed args');
- result = _.pick(['a', 'b'], 1);
- assert.deepEqual(result, {1: 'b'}, 'can pick numeric properties');
-
- _.each([null, void 0], function(val) {
- assert.deepEqual(_.pick(val, 'hasOwnProperty'), {}, 'Called with null/undefined');
- assert.deepEqual(_.pick(val, _.constant(true)), {});
- });
- assert.deepEqual(_.pick(5, 'toString', 'b'), {toString: Number.prototype.toString}, 'can iterate primitives');
-
- var data = {a: 1, b: 2, c: 3};
- var callback = function(value, key, object) {
- assert.strictEqual(key, {1: 'a', 2: 'b', 3: 'c'}[value]);
- assert.strictEqual(object, data);
- return value !== this.value;
- };
- result = _.pick(data, callback, {value: 2});
- assert.deepEqual(result, {a: 1, c: 3}, 'can accept a predicate and context');
-
- var Obj = function(){};
- Obj.prototype = {a: 1, b: 2, c: 3};
- var instance = new Obj();
- assert.deepEqual(_.pick(instance, 'a', 'c'), {a: 1, c: 3}, 'include prototype props');
-
- assert.deepEqual(_.pick(data, function(val, key) {
- return this[key] === 3 && this === instance;
- }, instance), {c: 3}, 'function is given context');
-
- assert.ok(!_.has(_.pick({}, 'foo'), 'foo'), 'does not set own property if property not in object');
- _.pick(data, function(value, key, obj) {
- assert.equal(obj, data, 'passes same object as third parameter of iteratee');
- });
- });
-
- QUnit.test('omit', function(assert) {
- var result;
- result = _.omit({a: 1, b: 2, c: 3}, 'b');
- assert.deepEqual(result, {a: 1, c: 3}, 'can omit a single named property');
- result = _.omit({a: 1, b: 2, c: 3}, 'a', 'c');
- assert.deepEqual(result, {b: 2}, 'can omit several named properties');
- result = _.omit({a: 1, b: 2, c: 3}, ['b', 'c']);
- assert.deepEqual(result, {a: 1}, 'can omit properties named in an array');
- result = _.omit(['a', 'b'], 0);
- assert.deepEqual(result, {1: 'b'}, 'can omit numeric properties');
-
- assert.deepEqual(_.omit(null, 'a', 'b'), {}, 'non objects return empty object');
- assert.deepEqual(_.omit(void 0, 'toString'), {}, 'null/undefined return empty object');
- assert.deepEqual(_.omit(5, 'toString', 'b'), {}, 'returns empty object for primitives');
-
- var data = {a: 1, b: 2, c: 3};
- var callback = function(value, key, object) {
- assert.strictEqual(key, {1: 'a', 2: 'b', 3: 'c'}[value]);
- assert.strictEqual(object, data);
- return value !== this.value;
- };
- result = _.omit(data, callback, {value: 2});
- assert.deepEqual(result, {b: 2}, 'can accept a predicate');
-
- var Obj = function(){};
- Obj.prototype = {a: 1, b: 2, c: 3};
- var instance = new Obj();
- assert.deepEqual(_.omit(instance, 'b'), {a: 1, c: 3}, 'include prototype props');
-
- assert.deepEqual(_.omit(data, function(val, key) {
- return this[key] === 3 && this === instance;
- }, instance), {a: 1, b: 2}, 'function is given context');
- });
-
- QUnit.test('defaults', function(assert) {
- var options = {zero: 0, one: 1, empty: '', nan: NaN, nothing: null};
-
- _.defaults(options, {zero: 1, one: 10, twenty: 20, nothing: 'str'});
- assert.equal(options.zero, 0, 'value exists');
- assert.equal(options.one, 1, 'value exists');
- assert.equal(options.twenty, 20, 'default applied');
- assert.equal(options.nothing, null, "null isn't overridden");
-
- _.defaults(options, {empty: 'full'}, {nan: 'nan'}, {word: 'word'}, {word: 'dog'});
- assert.equal(options.empty, '', 'value exists');
- assert.ok(_.isNaN(options.nan), "NaN isn't overridden");
- assert.equal(options.word, 'word', 'new value is added, first one wins');
-
- try {
- options = {};
- _.defaults(options, null, void 0, {a: 1});
- } catch (e) { /* ignored */ }
-
- assert.equal(options.a, 1, 'should not error on `null` or `undefined` sources');
-
- assert.deepEqual(_.defaults(null, {a: 1}), {a: 1}, 'defaults skips nulls');
- assert.deepEqual(_.defaults(void 0, {a: 1}), {a: 1}, 'defaults skips undefined');
- });
-
- QUnit.test('clone', function(assert) {
- var moe = {name: 'moe', lucky: [13, 27, 34]};
- var clone = _.clone(moe);
- assert.equal(clone.name, 'moe', 'the clone as the attributes of the original');
-
- clone.name = 'curly';
- assert.ok(clone.name === 'curly' && moe.name === 'moe', 'clones can change shallow attributes without affecting the original');
-
- clone.lucky.push(101);
- assert.equal(_.last(moe.lucky), 101, 'changes to deep attributes are shared with the original');
-
- assert.equal(_.clone(void 0), void 0, 'non objects should not be changed by clone');
- assert.equal(_.clone(1), 1, 'non objects should not be changed by clone');
- assert.equal(_.clone(null), null, 'non objects should not be changed by clone');
- });
-
- QUnit.test('create', function(assert) {
- var Parent = function() {};
- Parent.prototype = {foo: function() {}, bar: 2};
-
- _.each(['foo', null, void 0, 1], function(val) {
- assert.deepEqual(_.create(val), {}, 'should return empty object when a non-object is provided');
- });
-
- assert.ok(_.create([]) instanceof Array, 'should return new instance of array when array is provided');
-
- var Child = function() {};
- Child.prototype = _.create(Parent.prototype);
- assert.ok(new Child instanceof Parent, 'object should inherit prototype');
-
- var func = function() {};
- Child.prototype = _.create(Parent.prototype, {func: func});
- assert.strictEqual(Child.prototype.func, func, 'properties should be added to object');
-
- Child.prototype = _.create(Parent.prototype, {constructor: Child});
- assert.strictEqual(Child.prototype.constructor, Child);
-
- Child.prototype.foo = 'foo';
- var created = _.create(Child.prototype, new Child);
- assert.ok(!created.hasOwnProperty('foo'), 'should only add own properties');
- });
-
- QUnit.test('isEqual', function(assert) {
- function First() {
- this.value = 1;
- }
- First.prototype.value = 1;
- function Second() {
- this.value = 1;
- }
- Second.prototype.value = 2;
-
- // Basic equality and identity comparisons.
- assert.ok(_.isEqual(null, null), '`null` is equal to `null`');
- assert.ok(_.isEqual(), '`undefined` is equal to `undefined`');
-
- assert.ok(!_.isEqual(0, -0), '`0` is not equal to `-0`');
- assert.ok(!_.isEqual(-0, 0), 'Commutative equality is implemented for `0` and `-0`');
- assert.ok(!_.isEqual(null, void 0), '`null` is not equal to `undefined`');
- assert.ok(!_.isEqual(void 0, null), 'Commutative equality is implemented for `null` and `undefined`');
-
- // String object and primitive comparisons.
- assert.ok(_.isEqual('Curly', 'Curly'), 'Identical string primitives are equal');
- assert.ok(_.isEqual(new String('Curly'), new String('Curly')), 'String objects with identical primitive values are equal');
- assert.ok(_.isEqual(new String('Curly'), 'Curly'), 'String primitives and their corresponding object wrappers are equal');
- assert.ok(_.isEqual('Curly', new String('Curly')), 'Commutative equality is implemented for string objects and primitives');
-
- assert.ok(!_.isEqual('Curly', 'Larry'), 'String primitives with different values are not equal');
- assert.ok(!_.isEqual(new String('Curly'), new String('Larry')), 'String objects with different primitive values are not equal');
- assert.ok(!_.isEqual(new String('Curly'), {toString: function(){ return 'Curly'; }}), 'String objects and objects with a custom `toString` method are not equal');
-
- // Number object and primitive comparisons.
- assert.ok(_.isEqual(75, 75), 'Identical number primitives are equal');
- assert.ok(_.isEqual(new Number(75), new Number(75)), 'Number objects with identical primitive values are equal');
- assert.ok(_.isEqual(75, new Number(75)), 'Number primitives and their corresponding object wrappers are equal');
- assert.ok(_.isEqual(new Number(75), 75), 'Commutative equality is implemented for number objects and primitives');
- assert.ok(!_.isEqual(new Number(0), -0), '`new Number(0)` and `-0` are not equal');
- assert.ok(!_.isEqual(0, new Number(-0)), 'Commutative equality is implemented for `new Number(0)` and `-0`');
-
- assert.ok(!_.isEqual(new Number(75), new Number(63)), 'Number objects with different primitive values are not equal');
- assert.ok(!_.isEqual(new Number(63), {valueOf: function(){ return 63; }}), 'Number objects and objects with a `valueOf` method are not equal');
-
- // Comparisons involving `NaN`.
- assert.ok(_.isEqual(NaN, NaN), '`NaN` is equal to `NaN`');
- assert.ok(_.isEqual(new Number(NaN), NaN), 'Object(`NaN`) is equal to `NaN`');
- assert.ok(!_.isEqual(61, NaN), 'A number primitive is not equal to `NaN`');
- assert.ok(!_.isEqual(new Number(79), NaN), 'A number object is not equal to `NaN`');
- assert.ok(!_.isEqual(Infinity, NaN), '`Infinity` is not equal to `NaN`');
-
- // Boolean object and primitive comparisons.
- assert.ok(_.isEqual(true, true), 'Identical boolean primitives are equal');
- assert.ok(_.isEqual(new Boolean, new Boolean), 'Boolean objects with identical primitive values are equal');
- assert.ok(_.isEqual(true, new Boolean(true)), 'Boolean primitives and their corresponding object wrappers are equal');
- assert.ok(_.isEqual(new Boolean(true), true), 'Commutative equality is implemented for booleans');
- assert.ok(!_.isEqual(new Boolean(true), new Boolean), 'Boolean objects with different primitive values are not equal');
-
- // Common type coercions.
- assert.ok(!_.isEqual(new Boolean(false), true), '`new Boolean(false)` is not equal to `true`');
- assert.ok(!_.isEqual('75', 75), 'String and number primitives with like values are not equal');
- assert.ok(!_.isEqual(new Number(63), new String(63)), 'String and number objects with like values are not equal');
- assert.ok(!_.isEqual(75, '75'), 'Commutative equality is implemented for like string and number values');
- assert.ok(!_.isEqual(0, ''), 'Number and string primitives with like values are not equal');
- assert.ok(!_.isEqual(1, true), 'Number and boolean primitives with like values are not equal');
- assert.ok(!_.isEqual(new Boolean(false), new Number(0)), 'Boolean and number objects with like values are not equal');
- assert.ok(!_.isEqual(false, new String('')), 'Boolean primitives and string objects with like values are not equal');
- assert.ok(!_.isEqual(12564504e5, new Date(2009, 9, 25)), 'Dates and their corresponding numeric primitive values are not equal');
-
- // Dates.
- assert.ok(_.isEqual(new Date(2009, 9, 25), new Date(2009, 9, 25)), 'Date objects referencing identical times are equal');
- assert.ok(!_.isEqual(new Date(2009, 9, 25), new Date(2009, 11, 13)), 'Date objects referencing different times are not equal');
- assert.ok(!_.isEqual(new Date(2009, 11, 13), {
- getTime: function(){
- return 12606876e5;
- }
- }), 'Date objects and objects with a `getTime` method are not equal');
- assert.ok(!_.isEqual(new Date('Curly'), new Date('Curly')), 'Invalid dates are not equal');
-
- // Functions.
- assert.ok(!_.isEqual(First, Second), 'Different functions with identical bodies and source code representations are not equal');
-
- // RegExps.
- assert.ok(_.isEqual(/(?:)/gim, /(?:)/gim), 'RegExps with equivalent patterns and flags are equal');
- assert.ok(_.isEqual(/(?:)/gi, /(?:)/ig), 'Flag order is not significant');
- assert.ok(!_.isEqual(/(?:)/g, /(?:)/gi), 'RegExps with equivalent patterns and different flags are not equal');
- assert.ok(!_.isEqual(/Moe/gim, /Curly/gim), 'RegExps with different patterns and equivalent flags are not equal');
- assert.ok(!_.isEqual(/(?:)/gi, /(?:)/g), 'Commutative equality is implemented for RegExps');
- assert.ok(!_.isEqual(/Curly/g, {source: 'Larry', global: true, ignoreCase: false, multiline: false}), 'RegExps and RegExp-like objects are not equal');
-
- // Empty arrays, array-like objects, and object literals.
- assert.ok(_.isEqual({}, {}), 'Empty object literals are equal');
- assert.ok(_.isEqual([], []), 'Empty array literals are equal');
- assert.ok(_.isEqual([{}], [{}]), 'Empty nested arrays and objects are equal');
- assert.ok(!_.isEqual({length: 0}, []), 'Array-like objects and arrays are not equal.');
- assert.ok(!_.isEqual([], {length: 0}), 'Commutative equality is implemented for array-like objects');
-
- assert.ok(!_.isEqual({}, []), 'Object literals and array literals are not equal');
- assert.ok(!_.isEqual([], {}), 'Commutative equality is implemented for objects and arrays');
-
- // Arrays with primitive and object values.
- assert.ok(_.isEqual([1, 'Larry', true], [1, 'Larry', true]), 'Arrays containing identical primitives are equal');
- assert.ok(_.isEqual([/Moe/g, new Date(2009, 9, 25)], [/Moe/g, new Date(2009, 9, 25)]), 'Arrays containing equivalent elements are equal');
-
- // Multi-dimensional arrays.
- var a = [new Number(47), false, 'Larry', /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}];
- var b = [new Number(47), false, 'Larry', /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}];
- assert.ok(_.isEqual(a, b), 'Arrays containing nested arrays and objects are recursively compared');
-
- // Overwrite the methods defined in ES 5.1 section 15.4.4.
- a.forEach = a.map = a.filter = a.every = a.indexOf = a.lastIndexOf = a.some = a.reduce = a.reduceRight = null;
- b.join = b.pop = b.reverse = b.shift = b.slice = b.splice = b.concat = b.sort = b.unshift = null;
-
- // Array elements and properties.
- assert.ok(_.isEqual(a, b), 'Arrays containing equivalent elements and different non-numeric properties are equal');
- a.push('White Rocks');
- assert.ok(!_.isEqual(a, b), 'Arrays of different lengths are not equal');
- a.push('East Boulder');
- b.push('Gunbarrel Ranch', 'Teller Farm');
- assert.ok(!_.isEqual(a, b), 'Arrays of identical lengths containing different elements are not equal');
-
- // Sparse arrays.
- assert.ok(_.isEqual(Array(3), Array(3)), 'Sparse arrays of identical lengths are equal');
- assert.ok(!_.isEqual(Array(3), Array(6)), 'Sparse arrays of different lengths are not equal when both are empty');
-
- var sparse = [];
- sparse[1] = 5;
- assert.ok(_.isEqual(sparse, [void 0, 5]), 'Handles sparse arrays as dense');
-
- // Simple objects.
- assert.ok(_.isEqual({a: 'Curly', b: 1, c: true}, {a: 'Curly', b: 1, c: true}), 'Objects containing identical primitives are equal');
- assert.ok(_.isEqual({a: /Curly/g, b: new Date(2009, 11, 13)}, {a: /Curly/g, b: new Date(2009, 11, 13)}), 'Objects containing equivalent members are equal');
- assert.ok(!_.isEqual({a: 63, b: 75}, {a: 61, b: 55}), 'Objects of identical sizes with different values are not equal');
- assert.ok(!_.isEqual({a: 63, b: 75}, {a: 61, c: 55}), 'Objects of identical sizes with different property names are not equal');
- assert.ok(!_.isEqual({a: 1, b: 2}, {a: 1}), 'Objects of different sizes are not equal');
- assert.ok(!_.isEqual({a: 1}, {a: 1, b: 2}), 'Commutative equality is implemented for objects');
- assert.ok(!_.isEqual({x: 1, y: void 0}, {x: 1, z: 2}), 'Objects with identical keys and different values are not equivalent');
-
- // `A` contains nested objects and arrays.
- a = {
- name: new String('Moe Howard'),
- age: new Number(77),
- stooge: true,
- hobbies: ['acting'],
- film: {
- name: 'Sing a Song of Six Pants',
- release: new Date(1947, 9, 30),
- stars: [new String('Larry Fine'), 'Shemp Howard'],
- minutes: new Number(16),
- seconds: 54
- }
- };
-
- // `B` contains equivalent nested objects and arrays.
- b = {
- name: new String('Moe Howard'),
- age: new Number(77),
- stooge: true,
- hobbies: ['acting'],
- film: {
- name: 'Sing a Song of Six Pants',
- release: new Date(1947, 9, 30),
- stars: [new String('Larry Fine'), 'Shemp Howard'],
- minutes: new Number(16),
- seconds: 54
- }
- };
- assert.ok(_.isEqual(a, b), 'Objects with nested equivalent members are recursively compared');
-
- // Instances.
- assert.ok(_.isEqual(new First, new First), 'Object instances are equal');
- assert.ok(!_.isEqual(new First, new Second), 'Objects with different constructors and identical own properties are not equal');
- assert.ok(!_.isEqual({value: 1}, new First), 'Object instances and objects sharing equivalent properties are not equal');
- assert.ok(!_.isEqual({value: 2}, new Second), 'The prototype chain of objects should not be examined');
-
- // Circular Arrays.
- (a = []).push(a);
- (b = []).push(b);
- assert.ok(_.isEqual(a, b), 'Arrays containing circular references are equal');
- a.push(new String('Larry'));
- b.push(new String('Larry'));
- assert.ok(_.isEqual(a, b), 'Arrays containing circular references and equivalent properties are equal');
- a.push('Shemp');
- b.push('Curly');
- assert.ok(!_.isEqual(a, b), 'Arrays containing circular references and different properties are not equal');
-
- // More circular arrays #767.
- a = ['everything is checked but', 'this', 'is not'];
- a[1] = a;
- b = ['everything is checked but', ['this', 'array'], 'is not'];
- assert.ok(!_.isEqual(a, b), 'Comparison of circular references with non-circular references are not equal');
-
- // Circular Objects.
- a = {abc: null};
- b = {abc: null};
- a.abc = a;
- b.abc = b;
- assert.ok(_.isEqual(a, b), 'Objects containing circular references are equal');
- a.def = 75;
- b.def = 75;
- assert.ok(_.isEqual(a, b), 'Objects containing circular references and equivalent properties are equal');
- a.def = new Number(75);
- b.def = new Number(63);
- assert.ok(!_.isEqual(a, b), 'Objects containing circular references and different properties are not equal');
-
- // More circular objects #767.
- a = {everything: 'is checked', but: 'this', is: 'not'};
- a.but = a;
- b = {everything: 'is checked', but: {that: 'object'}, is: 'not'};
- assert.ok(!_.isEqual(a, b), 'Comparison of circular references with non-circular object references are not equal');
-
- // Cyclic Structures.
- a = [{abc: null}];
- b = [{abc: null}];
- (a[0].abc = a).push(a);
- (b[0].abc = b).push(b);
- assert.ok(_.isEqual(a, b), 'Cyclic structures are equal');
- a[0].def = 'Larry';
- b[0].def = 'Larry';
- assert.ok(_.isEqual(a, b), 'Cyclic structures containing equivalent properties are equal');
- a[0].def = new String('Larry');
- b[0].def = new String('Curly');
- assert.ok(!_.isEqual(a, b), 'Cyclic structures containing different properties are not equal');
-
- // Complex Circular References.
- a = {foo: {b: {foo: {c: {foo: null}}}}};
- b = {foo: {b: {foo: {c: {foo: null}}}}};
- a.foo.b.foo.c.foo = a;
- b.foo.b.foo.c.foo = b;
- assert.ok(_.isEqual(a, b), 'Cyclic structures with nested and identically-named properties are equal');
-
- // Chaining.
- assert.ok(!_.isEqual(_({x: 1, y: void 0}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal');
-
- a = _({x: 1, y: 2}).chain();
- b = _({x: 1, y: 2}).chain();
- assert.equal(_.isEqual(a.isEqual(b), _(true)), true, '`isEqual` can be chained');
-
- // Objects without a `constructor` property
- if (Object.create) {
- a = Object.create(null, {x: {value: 1, enumerable: true}});
- b = {x: 1};
- assert.ok(_.isEqual(a, b), 'Handles objects without a constructor (e.g. from Object.create');
- }
-
- function Foo() { this.a = 1; }
- Foo.prototype.constructor = null;
-
- var other = {a: 1};
- assert.strictEqual(_.isEqual(new Foo, other), false, 'Objects from different constructors are not equal');
-
-
- // Tricky object cases val comparisions
- assert.equal(_.isEqual([0], [-0]), false);
- assert.equal(_.isEqual({a: 0}, {a: -0}), false);
- assert.equal(_.isEqual([NaN], [NaN]), true);
- assert.equal(_.isEqual({a: NaN}, {a: NaN}), true);
-
- if (typeof Symbol !== 'undefined') {
- var symbol = Symbol('x');
- assert.strictEqual(_.isEqual(symbol, symbol), true, 'A symbol is equal to itself');
- assert.strictEqual(_.isEqual(symbol, Object(symbol)), true, 'Even when wrapped in Object()');
- assert.strictEqual(_.isEqual(symbol, null), false, 'Different types are not equal');
- }
-
- });
-
- QUnit.test('isEmpty', function(assert) {
- assert.ok(!_([1]).isEmpty(), '[1] is not empty');
- assert.ok(_.isEmpty([]), '[] is empty');
- assert.ok(!_.isEmpty({one: 1}), '{one: 1} is not empty');
- assert.ok(_.isEmpty({}), '{} is empty');
- assert.ok(_.isEmpty(new RegExp('')), 'objects with prototype properties are empty');
- assert.ok(_.isEmpty(null), 'null is empty');
- assert.ok(_.isEmpty(), 'undefined is empty');
- assert.ok(_.isEmpty(''), 'the empty string is empty');
- assert.ok(!_.isEmpty('moe'), 'but other strings are not');
-
- var obj = {one: 1};
- delete obj.one;
- assert.ok(_.isEmpty(obj), 'deleting all the keys from an object empties it');
-
- var args = function(){ return arguments; };
- assert.ok(_.isEmpty(args()), 'empty arguments object is empty');
- assert.ok(!_.isEmpty(args('')), 'non-empty arguments object is not empty');
-
- // covers collecting non-enumerable properties in IE < 9
- var nonEnumProp = {toString: 5};
- assert.ok(!_.isEmpty(nonEnumProp), 'non-enumerable property is not empty');
- });
-
- if (typeof document === 'object') {
- QUnit.test('isElement', function(assert) {
- assert.ok(!_.isElement('div'), 'strings are not dom elements');
- assert.ok(_.isElement(testElement), 'an element is a DOM element');
- });
- }
-
- QUnit.test('isArguments', function(assert) {
- var args = (function(){ return arguments; }(1, 2, 3));
- assert.ok(!_.isArguments('string'), 'a string is not an arguments object');
- assert.ok(!_.isArguments(_.isArguments), 'a function is not an arguments object');
- assert.ok(_.isArguments(args), 'but the arguments object is an arguments object');
- assert.ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array');
- assert.ok(!_.isArguments([1, 2, 3]), 'and not vanilla arrays.');
- });
-
- QUnit.test('isObject', function(assert) {
- assert.ok(_.isObject(arguments), 'the arguments object is object');
- assert.ok(_.isObject([1, 2, 3]), 'and arrays');
- if (testElement) {
- assert.ok(_.isObject(testElement), 'and DOM element');
- }
- assert.ok(_.isObject(function() {}), 'and functions');
- assert.ok(!_.isObject(null), 'but not null');
- assert.ok(!_.isObject(void 0), 'and not undefined');
- assert.ok(!_.isObject('string'), 'and not string');
- assert.ok(!_.isObject(12), 'and not number');
- assert.ok(!_.isObject(true), 'and not boolean');
- assert.ok(_.isObject(new String('string')), 'but new String()');
- });
-
- QUnit.test('isArray', function(assert) {
- assert.ok(!_.isArray(void 0), 'undefined vars are not arrays');
- assert.ok(!_.isArray(arguments), 'the arguments object is not an array');
- assert.ok(_.isArray([1, 2, 3]), 'but arrays are');
- });
-
- QUnit.test('isString', function(assert) {
- var obj = new String('I am a string object');
- if (testElement) {
- assert.ok(!_.isString(testElement), 'an element is not a string');
- }
- assert.ok(_.isString([1, 2, 3].join(', ')), 'but strings are');
- assert.strictEqual(_.isString('I am a string literal'), true, 'string literals are');
- assert.ok(_.isString(obj), 'so are String objects');
- assert.strictEqual(_.isString(1), false);
- });
-
- QUnit.test('isSymbol', function(assert) {
- assert.ok(!_.isSymbol(0), 'numbers are not symbols');
- assert.ok(!_.isSymbol(''), 'strings are not symbols');
- assert.ok(!_.isSymbol(_.isSymbol), 'functions are not symbols');
- if (typeof Symbol === 'function') {
- assert.ok(_.isSymbol(Symbol()), 'symbols are symbols');
- assert.ok(_.isSymbol(Symbol('description')), 'described symbols are symbols');
- assert.ok(_.isSymbol(Object(Symbol())), 'boxed symbols are symbols');
- }
- });
-
- QUnit.test('isNumber', function(assert) {
- assert.ok(!_.isNumber('string'), 'a string is not a number');
- assert.ok(!_.isNumber(arguments), 'the arguments object is not a number');
- assert.ok(!_.isNumber(void 0), 'undefined is not a number');
- assert.ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are');
- assert.ok(_.isNumber(NaN), 'NaN *is* a number');
- assert.ok(_.isNumber(Infinity), 'Infinity is a number');
- assert.ok(!_.isNumber('1'), 'numeric strings are not numbers');
- });
-
- QUnit.test('isBoolean', function(assert) {
- assert.ok(!_.isBoolean(2), 'a number is not a boolean');
- assert.ok(!_.isBoolean('string'), 'a string is not a boolean');
- assert.ok(!_.isBoolean('false'), 'the string "false" is not a boolean');
- assert.ok(!_.isBoolean('true'), 'the string "true" is not a boolean');
- assert.ok(!_.isBoolean(arguments), 'the arguments object is not a boolean');
- assert.ok(!_.isBoolean(void 0), 'undefined is not a boolean');
- assert.ok(!_.isBoolean(NaN), 'NaN is not a boolean');
- assert.ok(!_.isBoolean(null), 'null is not a boolean');
- assert.ok(_.isBoolean(true), 'but true is');
- assert.ok(_.isBoolean(false), 'and so is false');
- });
-
- QUnit.test('isMap', function(assert) {
- assert.ok(!_.isMap('string'), 'a string is not a map');
- assert.ok(!_.isMap(2), 'a number is not a map');
- assert.ok(!_.isMap({}), 'an object is not a map');
- assert.ok(!_.isMap(false), 'a boolean is not a map');
- assert.ok(!_.isMap(void 0), 'undefined is not a map');
- assert.ok(!_.isMap([1, 2, 3]), 'an array is not a map');
- if (typeof Set === 'function') {
- assert.ok(!_.isMap(new Set()), 'a set is not a map');
- }
- if (typeof WeakSet === 'function') {
- assert.ok(!_.isMap(new WeakSet()), 'a weakset is not a map');
- }
- if (typeof WeakMap === 'function') {
- assert.ok(!_.isMap(new WeakMap()), 'a weakmap is not a map');
- }
- if (typeof Map === 'function') {
- var keyString = 'a string';
- var obj = new Map();
- obj.set(keyString, 'value');
- assert.ok(_.isMap(obj), 'but a map is');
- }
- });
-
- QUnit.test('isWeakMap', function(assert) {
- assert.ok(!_.isWeakMap('string'), 'a string is not a weakmap');
- assert.ok(!_.isWeakMap(2), 'a number is not a weakmap');
- assert.ok(!_.isWeakMap({}), 'an object is not a weakmap');
- assert.ok(!_.isWeakMap(false), 'a boolean is not a weakmap');
- assert.ok(!_.isWeakMap(void 0), 'undefined is not a weakmap');
- assert.ok(!_.isWeakMap([1, 2, 3]), 'an array is not a weakmap');
- if (typeof Set === 'function') {
- assert.ok(!_.isWeakMap(new Set()), 'a set is not a weakmap');
- }
- if (typeof WeakSet === 'function') {
- assert.ok(!_.isWeakMap(new WeakSet()), 'a weakset is not a weakmap');
- }
- if (typeof Map === 'function') {
- assert.ok(!_.isWeakMap(new Map()), 'a map is not a weakmap');
- }
- if (typeof WeakMap === 'function') {
- var keyObj = {}, obj = new WeakMap();
- obj.set(keyObj, 'value');
- assert.ok(_.isWeakMap(obj), 'but a weakmap is');
- }
- });
-
- QUnit.test('isSet', function(assert) {
- assert.ok(!_.isSet('string'), 'a string is not a set');
- assert.ok(!_.isSet(2), 'a number is not a set');
- assert.ok(!_.isSet({}), 'an object is not a set');
- assert.ok(!_.isSet(false), 'a boolean is not a set');
- assert.ok(!_.isSet(void 0), 'undefined is not a set');
- assert.ok(!_.isSet([1, 2, 3]), 'an array is not a set');
- if (typeof Map === 'function') {
- assert.ok(!_.isSet(new Map()), 'a map is not a set');
- }
- if (typeof WeakMap === 'function') {
- assert.ok(!_.isSet(new WeakMap()), 'a weakmap is not a set');
- }
- if (typeof WeakSet === 'function') {
- assert.ok(!_.isSet(new WeakSet()), 'a weakset is not a set');
- }
- if (typeof Set === 'function') {
- var obj = new Set();
- obj.add(1).add('string').add(false).add({});
- assert.ok(_.isSet(obj), 'but a set is');
- }
- });
-
- QUnit.test('isWeakSet', function(assert) {
-
- assert.ok(!_.isWeakSet('string'), 'a string is not a weakset');
- assert.ok(!_.isWeakSet(2), 'a number is not a weakset');
- assert.ok(!_.isWeakSet({}), 'an object is not a weakset');
- assert.ok(!_.isWeakSet(false), 'a boolean is not a weakset');
- assert.ok(!_.isWeakSet(void 0), 'undefined is not a weakset');
- assert.ok(!_.isWeakSet([1, 2, 3]), 'an array is not a weakset');
- if (typeof Map === 'function') {
- assert.ok(!_.isWeakSet(new Map()), 'a map is not a weakset');
- }
- if (typeof WeakMap === 'function') {
- assert.ok(!_.isWeakSet(new WeakMap()), 'a weakmap is not a weakset');
- }
- if (typeof Set === 'function') {
- assert.ok(!_.isWeakSet(new Set()), 'a set is not a weakset');
- }
- if (typeof WeakSet === 'function') {
- var obj = new WeakSet();
- obj.add({x: 1}, {y: 'string'}).add({y: 'string'}).add({z: [1, 2, 3]});
- assert.ok(_.isWeakSet(obj), 'but a weakset is');
- }
- });
-
- QUnit.test('isFunction', function(assert) {
- assert.ok(!_.isFunction(void 0), 'undefined vars are not functions');
- assert.ok(!_.isFunction([1, 2, 3]), 'arrays are not functions');
- assert.ok(!_.isFunction('moe'), 'strings are not functions');
- assert.ok(_.isFunction(_.isFunction), 'but functions are');
- assert.ok(_.isFunction(function(){}), 'even anonymous ones');
-
- if (testElement) {
- assert.ok(!_.isFunction(testElement), 'elements are not functions');
- }
-
- var nodelist = typeof document != 'undefined' && document.childNodes;
- if (nodelist) {
- assert.ok(!_.isFunction(nodelist));
- }
- });
-
- if (typeof Int8Array !== 'undefined') {
- QUnit.test('#1929 Typed Array constructors are functions', function(assert) {
- _.chain(['Float32Array', 'Float64Array', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array'])
- .map(_.propertyOf(typeof GLOBAL != 'undefined' ? GLOBAL : window))
- .compact()
- .each(function(TypedArray) {
- // PhantomJS reports `typeof UInt8Array == 'object'` and doesn't report toString TypeArray
- // as a function
- assert.strictEqual(_.isFunction(TypedArray), Object.prototype.toString.call(TypedArray) === '[object Function]');
- });
- });
- }
-
- QUnit.test('isDate', function(assert) {
- assert.ok(!_.isDate(100), 'numbers are not dates');
- assert.ok(!_.isDate({}), 'objects are not dates');
- assert.ok(_.isDate(new Date()), 'but dates are');
- });
-
- QUnit.test('isRegExp', function(assert) {
- assert.ok(!_.isRegExp(_.identity), 'functions are not RegExps');
- assert.ok(_.isRegExp(/identity/), 'but RegExps are');
- });
-
- QUnit.test('isFinite', function(assert) {
- assert.ok(!_.isFinite(void 0), 'undefined is not finite');
- assert.ok(!_.isFinite(null), 'null is not finite');
- assert.ok(!_.isFinite(NaN), 'NaN is not finite');
- assert.ok(!_.isFinite(Infinity), 'Infinity is not finite');
- assert.ok(!_.isFinite(-Infinity), '-Infinity is not finite');
- assert.ok(_.isFinite('12'), 'Numeric strings are numbers');
- assert.ok(!_.isFinite('1a'), 'Non numeric strings are not numbers');
- assert.ok(!_.isFinite(''), 'Empty strings are not numbers');
- var obj = new Number(5);
- assert.ok(_.isFinite(obj), 'Number instances can be finite');
- assert.ok(_.isFinite(0), '0 is finite');
- assert.ok(_.isFinite(123), 'Ints are finite');
- assert.ok(_.isFinite(-12.44), 'Floats are finite');
- if (typeof Symbol === 'function') {
- assert.ok(!_.isFinite(Symbol()), 'symbols are not numbers');
- assert.ok(!_.isFinite(Symbol('description')), 'described symbols are not numbers');
- assert.ok(!_.isFinite(Object(Symbol())), 'boxed symbols are not numbers');
- }
- });
-
- QUnit.test('isNaN', function(assert) {
- assert.ok(!_.isNaN(void 0), 'undefined is not NaN');
- assert.ok(!_.isNaN(null), 'null is not NaN');
- assert.ok(!_.isNaN(0), '0 is not NaN');
- assert.ok(!_.isNaN(new Number(0)), 'wrapped 0 is not NaN');
- assert.ok(_.isNaN(NaN), 'but NaN is');
- assert.ok(_.isNaN(new Number(NaN)), 'wrapped NaN is still NaN');
- });
-
- QUnit.test('isNull', function(assert) {
- assert.ok(!_.isNull(void 0), 'undefined is not null');
- assert.ok(!_.isNull(NaN), 'NaN is not null');
- assert.ok(_.isNull(null), 'but null is');
- });
-
- QUnit.test('isUndefined', function(assert) {
- assert.ok(!_.isUndefined(1), 'numbers are defined');
- assert.ok(!_.isUndefined(null), 'null is defined');
- assert.ok(!_.isUndefined(false), 'false is defined');
- assert.ok(!_.isUndefined(NaN), 'NaN is defined');
- assert.ok(_.isUndefined(), 'nothing is undefined');
- assert.ok(_.isUndefined(void 0), 'undefined is undefined');
- });
-
- QUnit.test('isError', function(assert) {
- assert.ok(!_.isError(1), 'numbers are not Errors');
- assert.ok(!_.isError(null), 'null is not an Error');
- assert.ok(!_.isError(Error), 'functions are not Errors');
- assert.ok(_.isError(new Error()), 'Errors are Errors');
- assert.ok(_.isError(new EvalError()), 'EvalErrors are Errors');
- assert.ok(_.isError(new RangeError()), 'RangeErrors are Errors');
- assert.ok(_.isError(new ReferenceError()), 'ReferenceErrors are Errors');
- assert.ok(_.isError(new SyntaxError()), 'SyntaxErrors are Errors');
- assert.ok(_.isError(new TypeError()), 'TypeErrors are Errors');
- assert.ok(_.isError(new URIError()), 'URIErrors are Errors');
- });
-
- QUnit.test('tap', function(assert) {
- var intercepted = null;
- var interceptor = function(obj) { intercepted = obj; };
- var returned = _.tap(1, interceptor);
- assert.equal(intercepted, 1, 'passes tapped object to interceptor');
- assert.equal(returned, 1, 'returns tapped object');
-
- returned = _([1, 2, 3]).chain().
- map(function(n){ return n * 2; }).
- max().
- tap(interceptor).
- value();
- assert.equal(returned, 6, 'can use tapped objects in a chain');
- assert.equal(intercepted, returned, 'can use tapped objects in a chain');
- });
-
- QUnit.test('has', function(assert) {
- var obj = {foo: 'bar', func: function(){}};
- assert.ok(_.has(obj, 'foo'), 'has() checks that the object has a property.');
- assert.ok(!_.has(obj, 'baz'), "has() returns false if the object doesn't have the property.");
- assert.ok(_.has(obj, 'func'), 'has() works for functions too.');
- obj.hasOwnProperty = null;
- assert.ok(_.has(obj, 'foo'), 'has() works even when the hasOwnProperty method is deleted.');
- var child = {};
- child.prototype = obj;
- assert.ok(!_.has(child, 'foo'), 'has() does not check the prototype chain for a property.');
- assert.strictEqual(_.has(null, 'foo'), false, 'has() returns false for null');
- assert.strictEqual(_.has(void 0, 'foo'), false, 'has() returns false for undefined');
- });
-
- QUnit.test('isMatch', function(assert) {
- var moe = {name: 'Moe Howard', hair: true};
- var curly = {name: 'Curly Howard', hair: false};
-
- assert.equal(_.isMatch(moe, {hair: true}), true, 'Returns a boolean');
- assert.equal(_.isMatch(curly, {hair: true}), false, 'Returns a boolean');
-
- assert.equal(_.isMatch(5, {__x__: void 0}), false, 'can match undefined props on primitives');
- assert.equal(_.isMatch({__x__: void 0}, {__x__: void 0}), true, 'can match undefined props');
-
- assert.equal(_.isMatch(null, {}), true, 'Empty spec called with null object returns true');
- assert.equal(_.isMatch(null, {a: 1}), false, 'Non-empty spec called with null object returns false');
-
- _.each([null, void 0], function(item) { assert.strictEqual(_.isMatch(item, null), true, 'null matches null'); });
- _.each([null, void 0], function(item) { assert.strictEqual(_.isMatch(item, null), true, 'null matches {}'); });
- assert.strictEqual(_.isMatch({b: 1}, {a: void 0}), false, 'handles undefined values (1683)');
-
- _.each([true, 5, NaN, null, void 0], function(item) {
- assert.strictEqual(_.isMatch({a: 1}, item), true, 'treats primitives as empty');
- });
-
- function Prototest() {}
- Prototest.prototype.x = 1;
- var specObj = new Prototest;
- assert.equal(_.isMatch({x: 2}, specObj), true, 'spec is restricted to own properties');
-
- specObj.y = 5;
- assert.equal(_.isMatch({x: 1, y: 5}, specObj), true);
- assert.equal(_.isMatch({x: 1, y: 4}, specObj), false);
-
- assert.ok(_.isMatch(specObj, {x: 1, y: 5}), 'inherited and own properties are checked on the test object');
-
- Prototest.x = 5;
- assert.ok(_.isMatch({x: 5, y: 1}, Prototest), 'spec can be a function');
-
- //null edge cases
- var oCon = {constructor: Object};
- assert.deepEqual(_.map([null, void 0, 5, {}], _.partial(_.isMatch, _, oCon)), [false, false, false, true], 'doesnt falsey match constructor on undefined/null');
- });
-
- QUnit.test('matcher', function(assert) {
- var moe = {name: 'Moe Howard', hair: true};
- var curly = {name: 'Curly Howard', hair: false};
- var stooges = [moe, curly];
-
- assert.equal(_.matcher({hair: true})(moe), true, 'Returns a boolean');
- assert.equal(_.matcher({hair: true})(curly), false, 'Returns a boolean');
-
- assert.equal(_.matcher({__x__: void 0})(5), false, 'can match undefined props on primitives');
- assert.equal(_.matcher({__x__: void 0})({__x__: void 0}), true, 'can match undefined props');
-
- assert.equal(_.matcher({})(null), true, 'Empty spec called with null object returns true');
- assert.equal(_.matcher({a: 1})(null), false, 'Non-empty spec called with null object returns false');
-
- assert.ok(_.find(stooges, _.matcher({hair: false})) === curly, 'returns a predicate that can be used by finding functions.');
- assert.ok(_.find(stooges, _.matcher(moe)) === moe, 'can be used to locate an object exists in a collection.');
- assert.deepEqual(_.filter([null, void 0], _.matcher({a: 1})), [], 'Do not throw on null values.');
-
- assert.deepEqual(_.filter([null, void 0], _.matcher(null)), [null, void 0], 'null matches null');
- assert.deepEqual(_.filter([null, void 0], _.matcher({})), [null, void 0], 'null matches {}');
- assert.deepEqual(_.filter([{b: 1}], _.matcher({a: void 0})), [], 'handles undefined values (1683)');
-
- _.each([true, 5, NaN, null, void 0], function(item) {
- assert.equal(_.matcher(item)({a: 1}), true, 'treats primitives as empty');
- });
-
- function Prototest() {}
- Prototest.prototype.x = 1;
- var specObj = new Prototest;
- var protospec = _.matcher(specObj);
- assert.equal(protospec({x: 2}), true, 'spec is restricted to own properties');
-
- specObj.y = 5;
- protospec = _.matcher(specObj);
- assert.equal(protospec({x: 1, y: 5}), true);
- assert.equal(protospec({x: 1, y: 4}), false);
-
- assert.ok(_.matcher({x: 1, y: 5})(specObj), 'inherited and own properties are checked on the test object');
-
- Prototest.x = 5;
- assert.ok(_.matcher(Prototest)({x: 5, y: 1}), 'spec can be a function');
-
- // #1729
- var o = {b: 1};
- var m = _.matcher(o);
-
- assert.equal(m({b: 1}), true);
- o.b = 2;
- o.a = 1;
- assert.equal(m({b: 1}), true, 'changing spec object doesnt change matches result');
-
-
- //null edge cases
- var oCon = _.matcher({constructor: Object});
- assert.deepEqual(_.map([null, void 0, 5, {}], oCon), [false, false, false, true], 'doesnt falsey match constructor on undefined/null');
- });
-
- QUnit.test('matches', function(assert) {
- assert.strictEqual(_.matches, _.matcher, 'is an alias for matcher');
- });
-
- QUnit.test('findKey', function(assert) {
- var objects = {
- a: {a: 0, b: 0},
- b: {a: 1, b: 1},
- c: {a: 2, b: 2}
- };
-
- assert.equal(_.findKey(objects, function(obj) {
- return obj.a === 0;
- }), 'a');
-
- assert.equal(_.findKey(objects, function(obj) {
- return obj.b * obj.a === 4;
- }), 'c');
-
- assert.equal(_.findKey(objects, 'a'), 'b', 'Uses lookupIterator');
-
- assert.equal(_.findKey(objects, function(obj) {
- return obj.b * obj.a === 5;
- }), void 0);
-
- assert.strictEqual(_.findKey([1, 2, 3, 4, 5, 6], function(obj) {
- return obj === 3;
- }), '2', 'Keys are strings');
-
- assert.strictEqual(_.findKey(objects, function(a) {
- return a.foo === null;
- }), void 0);
-
- _.findKey({a: {a: 1}}, function(a, key, obj) {
- assert.equal(key, 'a');
- assert.deepEqual(obj, {a: {a: 1}});
- assert.strictEqual(this, objects, 'called with context');
- }, objects);
-
- var array = [1, 2, 3, 4];
- array.match = 55;
- assert.strictEqual(_.findKey(array, function(x) { return x === 55; }), 'match', 'matches array-likes keys');
- });
-
-
- QUnit.test('mapObject', function(assert) {
- var obj = {a: 1, b: 2};
- var objects = {
- a: {a: 0, b: 0},
- b: {a: 1, b: 1},
- c: {a: 2, b: 2}
- };
-
- assert.deepEqual(_.mapObject(obj, function(val) {
- return val * 2;
- }), {a: 2, b: 4}, 'simple objects');
-
- assert.deepEqual(_.mapObject(objects, function(val) {
- return _.reduce(val, function(memo, v){
- return memo + v;
- }, 0);
- }), {a: 0, b: 2, c: 4}, 'nested objects');
-
- assert.deepEqual(_.mapObject(obj, function(val, key, o) {
- return o[key] * 2;
- }), {a: 2, b: 4}, 'correct keys');
-
- assert.deepEqual(_.mapObject([1, 2], function(val) {
- return val * 2;
- }), {0: 2, 1: 4}, 'check behavior for arrays');
-
- assert.deepEqual(_.mapObject(obj, function(val) {
- return val * this.multiplier;
- }, {multiplier: 3}), {a: 3, b: 6}, 'keep context');
-
- assert.deepEqual(_.mapObject({a: 1}, function() {
- return this.length;
- }, [1, 2]), {a: 2}, 'called with context');
-
- var ids = _.mapObject({length: 2, 0: {id: '1'}, 1: {id: '2'}}, function(n){
- return n.id;
- });
- assert.deepEqual(ids, {length: void 0, 0: '1', 1: '2'}, 'Check with array-like objects');
-
- // Passing a property name like _.pluck.
- var people = {a: {name: 'moe', age: 30}, b: {name: 'curly', age: 50}};
- assert.deepEqual(_.mapObject(people, 'name'), {a: 'moe', b: 'curly'}, 'predicate string map to object properties');
-
- _.each([null, void 0, 1, 'abc', [], {}, void 0], function(val){
- assert.deepEqual(_.mapObject(val, _.identity), {}, 'mapValue identity');
- });
-
- var Proto = function(){ this.a = 1; };
- Proto.prototype.b = 1;
- var protoObj = new Proto();
- assert.deepEqual(_.mapObject(protoObj, _.identity), {a: 1}, 'ignore inherited values from prototypes');
-
- });
-}());
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/utility.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/utility.js
deleted file mode 100644
index fbd54df3..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/test/utility.js
+++ /dev/null
@@ -1,420 +0,0 @@
-(function() {
- var _ = typeof require == 'function' ? require('..') : window._;
- var templateSettings;
-
- QUnit.module('Utility', {
-
- beforeEach: function() {
- templateSettings = _.clone(_.templateSettings);
- },
-
- afterEach: function() {
- _.templateSettings = templateSettings;
- }
-
- });
-
- if (typeof this == 'object') {
- QUnit.test('noConflict', function(assert) {
- var underscore = _.noConflict();
- assert.equal(underscore.identity(1), 1);
- if (typeof require != 'function') {
- assert.equal(this._, void 0, 'global underscore is removed');
- this._ = underscore;
- } else if (typeof global !== 'undefined') {
- delete global._;
- }
- });
- }
-
- if (typeof require == 'function') {
- QUnit.test('noConflict (node vm)', function(assert) {
- assert.expect(2);
- var done = assert.async();
- var fs = require('fs');
- var vm = require('vm');
- var filename = __dirname + '/../underscore.js';
- fs.readFile(filename, function(err, content){
- var sandbox = vm.createScript(
- content + 'this.underscore = this._.noConflict();',
- filename
- );
- var context = {_: 'oldvalue'};
- sandbox.runInNewContext(context);
- assert.equal(context._, 'oldvalue');
- assert.equal(context.underscore.VERSION, _.VERSION);
-
- done();
- });
- });
- }
-
- QUnit.test('#750 - Return _ instance.', function(assert) {
- assert.expect(2);
- var instance = _([]);
- assert.ok(_(instance) === instance);
- assert.ok(new _(instance) === instance);
- });
-
- QUnit.test('identity', function(assert) {
- var stooge = {name: 'moe'};
- assert.equal(_.identity(stooge), stooge, 'stooge is the same as his identity');
- });
-
- QUnit.test('constant', function(assert) {
- var stooge = {name: 'moe'};
- assert.equal(_.constant(stooge)(), stooge, 'should create a function that returns stooge');
- });
-
- QUnit.test('noop', function(assert) {
- assert.strictEqual(_.noop('curly', 'larry', 'moe'), void 0, 'should always return undefined');
- });
-
- QUnit.test('property', function(assert) {
- var stooge = {name: 'moe'};
- assert.equal(_.property('name')(stooge), 'moe', 'should return the property with the given name');
- assert.equal(_.property('name')(null), void 0, 'should return undefined for null values');
- assert.equal(_.property('name')(void 0), void 0, 'should return undefined for undefined values');
- });
-
- QUnit.test('propertyOf', function(assert) {
- var stoogeRanks = _.propertyOf({curly: 2, moe: 1, larry: 3});
- assert.equal(stoogeRanks('curly'), 2, 'should return the property with the given name');
- assert.equal(stoogeRanks(null), void 0, 'should return undefined for null values');
- assert.equal(stoogeRanks(void 0), void 0, 'should return undefined for undefined values');
-
- function MoreStooges() { this.shemp = 87; }
- MoreStooges.prototype = {curly: 2, moe: 1, larry: 3};
- var moreStoogeRanks = _.propertyOf(new MoreStooges());
- assert.equal(moreStoogeRanks('curly'), 2, 'should return properties from further up the prototype chain');
-
- var nullPropertyOf = _.propertyOf(null);
- assert.equal(nullPropertyOf('curly'), void 0, 'should return undefined when obj is null');
-
- var undefPropertyOf = _.propertyOf(void 0);
- assert.equal(undefPropertyOf('curly'), void 0, 'should return undefined when obj is undefined');
- });
-
- QUnit.test('random', function(assert) {
- var array = _.range(1000);
- var min = Math.pow(2, 31);
- var max = Math.pow(2, 62);
-
- assert.ok(_.every(array, function() {
- return _.random(min, max) >= min;
- }), 'should produce a random number greater than or equal to the minimum number');
-
- assert.ok(_.some(array, function() {
- return _.random(Number.MAX_VALUE) > 0;
- }), 'should produce a random number when passed `Number.MAX_VALUE`');
- });
-
- QUnit.test('now', function(assert) {
- var diff = _.now() - new Date().getTime();
- assert.ok(diff <= 0 && diff > -5, 'Produces the correct time in milliseconds');//within 5ms
- });
-
- QUnit.test('uniqueId', function(assert) {
- var ids = [], i = 0;
- while (i++ < 100) ids.push(_.uniqueId());
- assert.equal(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids');
- });
-
- QUnit.test('times', function(assert) {
- var vals = [];
- _.times(3, function(i) { vals.push(i); });
- assert.deepEqual(vals, [0, 1, 2], 'is 0 indexed');
- //
- vals = [];
- _(3).times(function(i) { vals.push(i); });
- assert.deepEqual(vals, [0, 1, 2], 'works as a wrapper');
- // collects return values
- assert.deepEqual([0, 1, 2], _.times(3, function(i) { return i; }), 'collects return values');
-
- assert.deepEqual(_.times(0, _.identity), []);
- assert.deepEqual(_.times(-1, _.identity), []);
- assert.deepEqual(_.times(parseFloat('-Infinity'), _.identity), []);
- });
-
- QUnit.test('mixin', function(assert) {
- _.mixin({
- myReverse: function(string) {
- return string.split('').reverse().join('');
- }
- });
- assert.equal(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _');
- assert.equal(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper');
- });
-
- QUnit.test('_.escape', function(assert) {
- assert.equal(_.escape(null), '');
- });
-
- QUnit.test('_.unescape', function(assert) {
- var string = 'Curly & Moe';
- assert.equal(_.unescape(null), '');
- assert.equal(_.unescape(_.escape(string)), string);
- assert.equal(_.unescape(string), string, 'don\'t unescape unnecessarily');
- });
-
- // Don't care what they escape them to just that they're escaped and can be unescaped
- QUnit.test('_.escape & unescape', function(assert) {
- // test & (&amp;) seperately obviously
- var escapeCharacters = ['<', '>', '"', '\'', '`'];
-
- _.each(escapeCharacters, function(escapeChar) {
- var s = 'a ' + escapeChar + ' string escaped';
- var e = _.escape(s);
- assert.notEqual(s, e, escapeChar + ' is escaped');
- assert.equal(s, _.unescape(e), escapeChar + ' can be unescaped');
-
- s = 'a ' + escapeChar + escapeChar + escapeChar + 'some more string' + escapeChar;
- e = _.escape(s);
-
- assert.equal(e.indexOf(escapeChar), -1, 'can escape multiple occurances of ' + escapeChar);
- assert.equal(_.unescape(e), s, 'multiple occurrences of ' + escapeChar + ' can be unescaped');
- });
-
- // handles multiple escape characters at once
- var joiner = ' other stuff ';
- var allEscaped = escapeCharacters.join(joiner);
- allEscaped += allEscaped;
- assert.ok(_.every(escapeCharacters, function(escapeChar) {
- return allEscaped.indexOf(escapeChar) !== -1;
- }), 'handles multiple characters');
- assert.ok(allEscaped.indexOf(joiner) >= 0, 'can escape multiple escape characters at the same time');
-
- // test & -> &amp;
- var str = 'some string & another string & yet another';
- var escaped = _.escape(str);
-
- assert.ok(escaped.indexOf('&') !== -1, 'handles & aka &amp;');
- assert.equal(_.unescape(str), str, 'can unescape &amp;');
- });
-
- QUnit.test('template', function(assert) {
- var basicTemplate = _.template("<%= thing %> is gettin' on my noives!");
- var result = basicTemplate({thing: 'This'});
- assert.equal(result, "This is gettin' on my noives!", 'can do basic attribute interpolation');
-
- var sansSemicolonTemplate = _.template('A <% this %> B');
- assert.equal(sansSemicolonTemplate(), 'A B');
-
- var backslashTemplate = _.template('<%= thing %> is \\ridanculous');
- assert.equal(backslashTemplate({thing: 'This'}), 'This is \\ridanculous');
-
- var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>');
- assert.equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.');
-
- var fancyTemplate = _.template('<ul><% ' +
- ' for (var key in people) { ' +
- '%><li><%= people[key] %></li><% } %></ul>');
- result = fancyTemplate({people: {moe: 'Moe', larry: 'Larry', curly: 'Curly'}});
- assert.equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
-
- var escapedCharsInJavascriptTemplate = _.template('<ul><% _.each(numbers.split("\\n"), function(item) { %><li><%= item %></li><% }) %></ul>');
- result = escapedCharsInJavascriptTemplate({numbers: 'one\ntwo\nthree\nfour'});
- assert.equal(result, '<ul><li>one</li><li>two</li><li>three</li><li>four</li></ul>', 'Can use escaped characters (e.g. \\n) in JavaScript');
-
- var namespaceCollisionTemplate = _.template('<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %><div class="thumbnail" rel="<%= p %>"></div><% }); %>');
- result = namespaceCollisionTemplate({
- pageCount: 3,
- thumbnails: {
- 1: 'p1-thumbnail.gif',
- 2: 'p2-thumbnail.gif',
- 3: 'p3-thumbnail.gif'
- }
- });
- assert.equal(result, '3 p3-thumbnail.gif <div class="thumbnail" rel="p1-thumbnail.gif"></div><div class="thumbnail" rel="p2-thumbnail.gif"></div><div class="thumbnail" rel="p3-thumbnail.gif"></div>');
-
- var noInterpolateTemplate = _.template('<div><p>Just some text. Hey, I know this is silly but it aids consistency.</p></div>');
- result = noInterpolateTemplate();
- assert.equal(result, '<div><p>Just some text. Hey, I know this is silly but it aids consistency.</p></div>');
-
- var quoteTemplate = _.template("It's its, not it's");
- assert.equal(quoteTemplate({}), "It's its, not it's");
-
- var quoteInStatementAndBody = _.template('<% ' +
- " if(foo == 'bar'){ " +
- "%>Statement quotes and 'quotes'.<% } %>");
- assert.equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
-
- var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.');
- assert.equal(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.');
-
- var template = _.template('<i><%- value %></i>');
- result = template({value: '<script>'});
- assert.equal(result, '<i>&lt;script&gt;</i>');
-
- var stooge = {
- name: 'Moe',
- template: _.template("I'm <%= this.name %>")
- };
- assert.equal(stooge.template(), "I'm Moe");
-
- template = _.template('\n ' +
- ' <%\n ' +
- ' // a comment\n ' +
- ' if (data) { data += 12345; }; %>\n ' +
- ' <li><%= data %></li>\n '
- );
- assert.equal(template({data: 12345}).replace(/\s/g, ''), '<li>24690</li>');
-
- _.templateSettings = {
- evaluate: /\{\{([\s\S]+?)\}\}/g,
- interpolate: /\{\{=([\s\S]+?)\}\}/g
- };
-
- var custom = _.template('<ul>{{ for (var key in people) { }}<li>{{= people[key] }}</li>{{ } }}</ul>');
- result = custom({people: {moe: 'Moe', larry: 'Larry', curly: 'Curly'}});
- assert.equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
-
- var customQuote = _.template("It's its, not it's");
- assert.equal(customQuote({}), "It's its, not it's");
-
- quoteInStatementAndBody = _.template("{{ if(foo == 'bar'){ }}Statement quotes and 'quotes'.{{ } }}");
- assert.equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
-
- _.templateSettings = {
- evaluate: /<\?([\s\S]+?)\?>/g,
- interpolate: /<\?=([\s\S]+?)\?>/g
- };
-
- var customWithSpecialChars = _.template('<ul><? for (var key in people) { ?><li><?= people[key] ?></li><? } ?></ul>');
- result = customWithSpecialChars({people: {moe: 'Moe', larry: 'Larry', curly: 'Curly'}});
- assert.equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
-
- var customWithSpecialCharsQuote = _.template("It's its, not it's");
- assert.equal(customWithSpecialCharsQuote({}), "It's its, not it's");
-
- quoteInStatementAndBody = _.template("<? if(foo == 'bar'){ ?>Statement quotes and 'quotes'.<? } ?>");
- assert.equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
-
- _.templateSettings = {
- interpolate: /\{\{(.+?)\}\}/g
- };
-
- var mustache = _.template('Hello {{planet}}!');
- assert.equal(mustache({planet: 'World'}), 'Hello World!', 'can mimic mustache.js');
-
- var templateWithNull = _.template('a null undefined {{planet}}');
- assert.equal(templateWithNull({planet: 'world'}), 'a null undefined world', 'can handle missing escape and evaluate settings');
- });
-
- QUnit.test('_.template provides the generated function source, when a SyntaxError occurs', function(assert) {
- var source;
- try {
- _.template('<b><%= if x %></b>');
- } catch (ex) {
- source = ex.source;
- }
- assert.ok(/__p/.test(source));
- });
-
- QUnit.test('_.template handles \\u2028 & \\u2029', function(assert) {
- var tmpl = _.template('<p>\u2028<%= "\\u2028\\u2029" %>\u2029</p>');
- assert.strictEqual(tmpl(), '<p>\u2028\u2028\u2029\u2029</p>');
- });
-
- QUnit.test('result calls functions and returns primitives', function(assert) {
- var obj = {w: '', x: 'x', y: function(){ return this.x; }};
- assert.strictEqual(_.result(obj, 'w'), '');
- assert.strictEqual(_.result(obj, 'x'), 'x');
- assert.strictEqual(_.result(obj, 'y'), 'x');
- assert.strictEqual(_.result(obj, 'z'), void 0);
- assert.strictEqual(_.result(null, 'x'), void 0);
- });
-
- QUnit.test('result returns a default value if object is null or undefined', function(assert) {
- assert.strictEqual(_.result(null, 'b', 'default'), 'default');
- assert.strictEqual(_.result(void 0, 'c', 'default'), 'default');
- assert.strictEqual(_.result(''.match('missing'), 1, 'default'), 'default');
- });
-
- QUnit.test('result returns a default value if property of object is missing', function(assert) {
- assert.strictEqual(_.result({d: null}, 'd', 'default'), null);
- assert.strictEqual(_.result({e: false}, 'e', 'default'), false);
- });
-
- QUnit.test('result only returns the default value if the object does not have the property or is undefined', function(assert) {
- assert.strictEqual(_.result({}, 'b', 'default'), 'default');
- assert.strictEqual(_.result({d: void 0}, 'd', 'default'), 'default');
- });
-
- QUnit.test('result does not return the default if the property of an object is found in the prototype', function(assert) {
- var Foo = function(){};
- Foo.prototype.bar = 1;
- assert.strictEqual(_.result(new Foo, 'bar', 2), 1);
- });
-
- QUnit.test('result does use the fallback when the result of invoking the property is undefined', function(assert) {
- var obj = {a: function() {}};
- assert.strictEqual(_.result(obj, 'a', 'failed'), void 0);
- });
-
- QUnit.test('result fallback can use a function', function(assert) {
- var obj = {a: [1, 2, 3]};
- assert.strictEqual(_.result(obj, 'b', _.constant(5)), 5);
- assert.strictEqual(_.result(obj, 'b', function() {
- return this.a;
- }), obj.a, 'called with context');
- });
-
- QUnit.test('_.templateSettings.variable', function(assert) {
- var s = '<%=data.x%>';
- var data = {x: 'x'};
- var tmp = _.template(s, {variable: 'data'});
- assert.strictEqual(tmp(data), 'x');
- _.templateSettings.variable = 'data';
- assert.strictEqual(_.template(s)(data), 'x');
- });
-
- QUnit.test('#547 - _.templateSettings is unchanged by custom settings.', function(assert) {
- assert.ok(!_.templateSettings.variable);
- _.template('', {}, {variable: 'x'});
- assert.ok(!_.templateSettings.variable);
- });
-
- QUnit.test('#556 - undefined template variables.', function(assert) {
- var template = _.template('<%=x%>');
- assert.strictEqual(template({x: null}), '');
- assert.strictEqual(template({x: void 0}), '');
-
- var templateEscaped = _.template('<%-x%>');
- assert.strictEqual(templateEscaped({x: null}), '');
- assert.strictEqual(templateEscaped({x: void 0}), '');
-
- var templateWithProperty = _.template('<%=x.foo%>');
- assert.strictEqual(templateWithProperty({x: {}}), '');
- assert.strictEqual(templateWithProperty({x: {}}), '');
-
- var templateWithPropertyEscaped = _.template('<%-x.foo%>');
- assert.strictEqual(templateWithPropertyEscaped({x: {}}), '');
- assert.strictEqual(templateWithPropertyEscaped({x: {}}), '');
- });
-
- QUnit.test('interpolate evaluates code only once.', function(assert) {
- assert.expect(2);
- var count = 0;
- var template = _.template('<%= f() %>');
- template({f: function(){ assert.ok(!count++); }});
-
- var countEscaped = 0;
- var templateEscaped = _.template('<%- f() %>');
- templateEscaped({f: function(){ assert.ok(!countEscaped++); }});
- });
-
- QUnit.test('#746 - _.template settings are not modified.', function(assert) {
- assert.expect(1);
- var settings = {};
- _.template('', null, settings);
- assert.deepEqual(settings, {});
- });
-
- QUnit.test('#779 - delimeters are applied to unescaped text.', function(assert) {
- assert.expect(1);
- var template = _.template('<<\nx\n>>', null, {evaluate: /<<(.*?)>>/g});
- assert.strictEqual(template(), '<<\nx\n>>');
- });
-
-}());
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/underscore-min.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/underscore-min.js
deleted file mode 100644
index f01025b7..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/underscore-min.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// Underscore.js 1.8.3
-// http://underscorejs.org
-// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
-// Underscore may be freely distributed under the MIT license.
-(function(){function n(n){function t(t,r,e,u,i,o){for(;i>=0&&o>i;i+=n){var a=u?u[i]:i;e=r(e,t[a],a,t)}return e}return function(r,e,u,i){e=b(e,i,4);var o=!k(r)&&m.keys(r),a=(o||r).length,c=n>0?0:a-1;return arguments.length<3&&(u=r[o?o[c]:c],c+=n),t(r,e,u,o,c,a)}}function t(n){return function(t,r,e){r=x(r,e);for(var u=O(t),i=n>0?0:u-1;i>=0&&u>i;i+=n)if(r(t[i],i,t))return i;return-1}}function r(n,t,r){return function(e,u,i){var o=0,a=O(e);if("number"==typeof i)n>0?o=i>=0?i:Math.max(i+a,o):a=i>=0?Math.min(i+1,a):i+a+1;else if(r&&i&&a)return i=r(e,u),e[i]===u?i:-1;if(u!==u)return i=t(l.call(e,o,a),m.isNaN),i>=0?i+o:-1;for(i=n>0?o:a-1;i>=0&&a>i;i+=n)if(e[i]===u)return i;return-1}}function e(n,t){var r=I.length,e=n.constructor,u=m.isFunction(e)&&e.prototype||a,i="constructor";for(m.has(n,i)&&!m.contains(t,i)&&t.push(i);r--;)i=I[r],i in n&&n[i]!==u[i]&&!m.contains(t,i)&&t.push(i)}var u=this,i=u._,o=Array.prototype,a=Object.prototype,c=Function.prototype,f=o.push,l=o.slice,s=a.toString,p=a.hasOwnProperty,h=Array.isArray,v=Object.keys,g=c.bind,y=Object.create,d=function(){},m=function(n){return n instanceof m?n:this instanceof m?void(this._wrapped=n):new m(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=m),exports._=m):u._=m,m.VERSION="1.8.3";var b=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}},x=function(n,t,r){return null==n?m.identity:m.isFunction(n)?b(n,t,r):m.isObject(n)?m.matcher(n):m.property(n)};m.iteratee=function(n,t){return x(n,t,1/0)};var _=function(n,t){return function(r){var e=arguments.length;if(2>e||null==r)return r;for(var u=1;e>u;u++)for(var i=arguments[u],o=n(i),a=o.length,c=0;a>c;c++){var f=o[c];t&&r[f]!==void 0||(r[f]=i[f])}return r}},j=function(n){if(!m.isObject(n))return{};if(y)return y(n);d.prototype=n;var t=new d;return d.prototype=null,t},w=function(n){return function(t){return null==t?void 0:t[n]}},A=Math.pow(2,53)-1,O=w("length"),k=function(n){var t=O(n);return"number"==typeof t&&t>=0&&A>=t};m.each=m.forEach=function(n,t,r){t=b(t,r);var e,u;if(k(n))for(e=0,u=n.length;u>e;e++)t(n[e],e,n);else{var i=m.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},m.map=m.collect=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=Array(u),o=0;u>o;o++){var a=e?e[o]:o;i[o]=t(n[a],a,n)}return i},m.reduce=m.foldl=m.inject=n(1),m.reduceRight=m.foldr=n(-1),m.find=m.detect=function(n,t,r){var e;return e=k(n)?m.findIndex(n,t,r):m.findKey(n,t,r),e!==void 0&&e!==-1?n[e]:void 0},m.filter=m.select=function(n,t,r){var e=[];return t=x(t,r),m.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e},m.reject=function(n,t,r){return m.filter(n,m.negate(x(t)),r)},m.every=m.all=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(!t(n[o],o,n))return!1}return!0},m.some=m.any=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(t(n[o],o,n))return!0}return!1},m.contains=m.includes=m.include=function(n,t,r,e){return k(n)||(n=m.values(n)),("number"!=typeof r||e)&&(r=0),m.indexOf(n,t,r)>=0},m.invoke=function(n,t){var r=l.call(arguments,2),e=m.isFunction(t);return m.map(n,function(n){var u=e?t:n[t];return null==u?u:u.apply(n,r)})},m.pluck=function(n,t){return m.map(n,m.property(t))},m.where=function(n,t){return m.filter(n,m.matcher(t))},m.findWhere=function(n,t){return m.find(n,m.matcher(t))},m.max=function(n,t,r){var e,u,i=-1/0,o=-1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],e>i&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(u>o||u===-1/0&&i===-1/0)&&(i=n,o=u)});return i},m.min=function(n,t,r){var e,u,i=1/0,o=1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],i>e&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(o>u||1/0===u&&1/0===i)&&(i=n,o=u)});return i},m.shuffle=function(n){for(var t,r=k(n)?n:m.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=m.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},m.sample=function(n,t,r){return null==t||r?(k(n)||(n=m.values(n)),n[m.random(n.length-1)]):m.shuffle(n).slice(0,Math.max(0,t))},m.sortBy=function(n,t,r){return t=x(t,r),m.pluck(m.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=x(r,e),m.each(t,function(e,i){var o=r(e,i,t);n(u,e,o)}),u}};m.groupBy=F(function(n,t,r){m.has(n,r)?n[r].push(t):n[r]=[t]}),m.indexBy=F(function(n,t,r){n[r]=t}),m.countBy=F(function(n,t,r){m.has(n,r)?n[r]++:n[r]=1}),m.toArray=function(n){return n?m.isArray(n)?l.call(n):k(n)?m.map(n,m.identity):m.values(n):[]},m.size=function(n){return null==n?0:k(n)?n.length:m.keys(n).length},m.partition=function(n,t,r){t=x(t,r);var e=[],u=[];return m.each(n,function(n,r,i){(t(n,r,i)?e:u).push(n)}),[e,u]},m.first=m.head=m.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:m.initial(n,n.length-t)},m.initial=function(n,t,r){return l.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},m.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:m.rest(n,Math.max(0,n.length-t))},m.rest=m.tail=m.drop=function(n,t,r){return l.call(n,null==t||r?1:t)},m.compact=function(n){return m.filter(n,m.identity)};var S=function(n,t,r,e){for(var u=[],i=0,o=e||0,a=O(n);a>o;o++){var c=n[o];if(k(c)&&(m.isArray(c)||m.isArguments(c))){t||(c=S(c,t,r));var f=0,l=c.length;for(u.length+=l;l>f;)u[i++]=c[f++]}else r||(u[i++]=c)}return u};m.flatten=function(n,t){return S(n,t,!1)},m.without=function(n){return m.difference(n,l.call(arguments,1))},m.uniq=m.unique=function(n,t,r,e){m.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=x(r,e));for(var u=[],i=[],o=0,a=O(n);a>o;o++){var c=n[o],f=r?r(c,o,n):c;t?(o&&i===f||u.push(c),i=f):r?m.contains(i,f)||(i.push(f),u.push(c)):m.contains(u,c)||u.push(c)}return u},m.union=function(){return m.uniq(S(arguments,!0,!0))},m.intersection=function(n){for(var t=[],r=arguments.length,e=0,u=O(n);u>e;e++){var i=n[e];if(!m.contains(t,i)){for(var o=1;r>o&&m.contains(arguments[o],i);o++);o===r&&t.push(i)}}return t},m.difference=function(n){var t=S(arguments,!0,!0,1);return m.filter(n,function(n){return!m.contains(t,n)})},m.zip=function(){return m.unzip(arguments)},m.unzip=function(n){for(var t=n&&m.max(n,O).length||0,r=Array(t),e=0;t>e;e++)r[e]=m.pluck(n,e);return r},m.object=function(n,t){for(var r={},e=0,u=O(n);u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},m.findIndex=t(1),m.findLastIndex=t(-1),m.sortedIndex=function(n,t,r,e){r=x(r,e,1);for(var u=r(t),i=0,o=O(n);o>i;){var a=Math.floor((i+o)/2);r(n[a])<u?i=a+1:o=a}return i},m.indexOf=r(1,m.findIndex,m.sortedIndex),m.lastIndexOf=r(-1,m.findLastIndex),m.range=function(n,t,r){null==t&&(t=n||0,n=0),r=r||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=Array(e),i=0;e>i;i++,n+=r)u[i]=n;return u};var E=function(n,t,r,e,u){if(!(e instanceof t))return n.apply(r,u);var i=j(n.prototype),o=n.apply(i,u);return m.isObject(o)?o:i};m.bind=function(n,t){if(g&&n.bind===g)return g.apply(n,l.call(arguments,1));if(!m.isFunction(n))throw new TypeError("Bind must be called on a function");var r=l.call(arguments,2),e=function(){return E(n,e,t,this,r.concat(l.call(arguments)))};return e},m.partial=function(n){var t=l.call(arguments,1),r=function(){for(var e=0,u=t.length,i=Array(u),o=0;u>o;o++)i[o]=t[o]===m?arguments[e++]:t[o];for(;e<arguments.length;)i.push(arguments[e++]);return E(n,r,this,this,i)};return r},m.bindAll=function(n){var t,r,e=arguments.length;if(1>=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=m.bind(n[r],n);return n},m.memoize=function(n,t){var r=function(e){var u=r.cache,i=""+(t?t.apply(this,arguments):e);return m.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},m.delay=function(n,t){var r=l.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},m.defer=m.partial(m.delay,m,1),m.throttle=function(n,t,r){var e,u,i,o=null,a=0;r||(r={});var c=function(){a=r.leading===!1?0:m.now(),o=null,i=n.apply(e,u),o||(e=u=null)};return function(){var f=m.now();a||r.leading!==!1||(a=f);var l=t-(f-a);return e=this,u=arguments,0>=l||l>t?(o&&(clearTimeout(o),o=null),a=f,i=n.apply(e,u),o||(e=u=null)):o||r.trailing===!1||(o=setTimeout(c,l)),i}},m.debounce=function(n,t,r){var e,u,i,o,a,c=function(){var f=m.now()-o;t>f&&f>=0?e=setTimeout(c,t-f):(e=null,r||(a=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,o=m.now();var f=r&&!e;return e||(e=setTimeout(c,t)),f&&(a=n.apply(i,u),i=u=null),a}},m.wrap=function(n,t){return m.partial(t,n)},m.negate=function(n){return function(){return!n.apply(this,arguments)}},m.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},m.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},m.before=function(n,t){var r;return function(){return--n>0&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}},m.once=m.partial(m.before,2);var M=!{toString:null}.propertyIsEnumerable("toString"),I=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];m.keys=function(n){if(!m.isObject(n))return[];if(v)return v(n);var t=[];for(var r in n)m.has(n,r)&&t.push(r);return M&&e(n,t),t},m.allKeys=function(n){if(!m.isObject(n))return[];var t=[];for(var r in n)t.push(r);return M&&e(n,t),t},m.values=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},m.mapObject=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=u.length,o={},a=0;i>a;a++)e=u[a],o[e]=t(n[e],e,n);return o},m.pairs=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},m.invert=function(n){for(var t={},r=m.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},m.functions=m.methods=function(n){var t=[];for(var r in n)m.isFunction(n[r])&&t.push(r);return t.sort()},m.extend=_(m.allKeys),m.extendOwn=m.assign=_(m.keys),m.findKey=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=0,o=u.length;o>i;i++)if(e=u[i],t(n[e],e,n))return e},m.pick=function(n,t,r){var e,u,i={},o=n;if(null==o)return i;m.isFunction(t)?(u=m.allKeys(o),e=b(t,r)):(u=S(arguments,!1,!1,1),e=function(n,t,r){return t in r},o=Object(o));for(var a=0,c=u.length;c>a;a++){var f=u[a],l=o[f];e(l,f,o)&&(i[f]=l)}return i},m.omit=function(n,t,r){if(m.isFunction(t))t=m.negate(t);else{var e=m.map(S(arguments,!1,!1,1),String);t=function(n,t){return!m.contains(e,t)}}return m.pick(n,t,r)},m.defaults=_(m.allKeys,!0),m.create=function(n,t){var r=j(n);return t&&m.extendOwn(r,t),r},m.clone=function(n){return m.isObject(n)?m.isArray(n)?n.slice():m.extend({},n):n},m.tap=function(n,t){return t(n),n},m.isMatch=function(n,t){var r=m.keys(t),e=r.length;if(null==n)return!e;for(var u=Object(n),i=0;e>i;i++){var o=r[i];if(t[o]!==u[o]||!(o in u))return!1}return!0};var N=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof m&&(n=n._wrapped),t instanceof m&&(t=t._wrapped);var u=s.call(n);if(u!==s.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}var i="[object Array]"===u;if(!i){if("object"!=typeof n||"object"!=typeof t)return!1;var o=n.constructor,a=t.constructor;if(o!==a&&!(m.isFunction(o)&&o instanceof o&&m.isFunction(a)&&a instanceof a)&&"constructor"in n&&"constructor"in t)return!1}r=r||[],e=e||[];for(var c=r.length;c--;)if(r[c]===n)return e[c]===t;if(r.push(n),e.push(t),i){if(c=n.length,c!==t.length)return!1;for(;c--;)if(!N(n[c],t[c],r,e))return!1}else{var f,l=m.keys(n);if(c=l.length,m.keys(t).length!==c)return!1;for(;c--;)if(f=l[c],!m.has(t,f)||!N(n[f],t[f],r,e))return!1}return r.pop(),e.pop(),!0};m.isEqual=function(n,t){return N(n,t)},m.isEmpty=function(n){return null==n?!0:k(n)&&(m.isArray(n)||m.isString(n)||m.isArguments(n))?0===n.length:0===m.keys(n).length},m.isElement=function(n){return!(!n||1!==n.nodeType)},m.isArray=h||function(n){return"[object Array]"===s.call(n)},m.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},m.each(["Arguments","Function","String","Number","Date","RegExp","Error"],function(n){m["is"+n]=function(t){return s.call(t)==="[object "+n+"]"}}),m.isArguments(arguments)||(m.isArguments=function(n){return m.has(n,"callee")}),"function"!=typeof/./&&"object"!=typeof Int8Array&&(m.isFunction=function(n){return"function"==typeof n||!1}),m.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},m.isNaN=function(n){return m.isNumber(n)&&n!==+n},m.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===s.call(n)},m.isNull=function(n){return null===n},m.isUndefined=function(n){return n===void 0},m.has=function(n,t){return null!=n&&p.call(n,t)},m.noConflict=function(){return u._=i,this},m.identity=function(n){return n},m.constant=function(n){return function(){return n}},m.noop=function(){},m.property=w,m.propertyOf=function(n){return null==n?function(){}:function(t){return n[t]}},m.matcher=m.matches=function(n){return n=m.extendOwn({},n),function(t){return m.isMatch(t,n)}},m.times=function(n,t,r){var e=Array(Math.max(0,n));t=b(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},m.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},m.now=Date.now||function(){return(new Date).getTime()};var B={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},T=m.invert(B),R=function(n){var t=function(t){return n[t]},r="(?:"+m.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};m.escape=R(B),m.unescape=R(T),m.result=function(n,t,r){var e=null==n?void 0:n[t];return e===void 0&&(e=r),m.isFunction(e)?e.call(n):e};var q=0;m.uniqueId=function(n){var t=++q+"";return n?n+t:t},m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var K=/(.)^/,z={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\u2028|\u2029/g,L=function(n){return"\\"+z[n]};m.template=function(n,t,r){!t&&r&&(t=r),t=m.defaults({},t,m.templateSettings);var e=RegExp([(t.escape||K).source,(t.interpolate||K).source,(t.evaluate||K).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,o,a){return i+=n.slice(u,a).replace(D,L),u=a+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":o&&(i+="';\n"+o+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var o=new Function(t.variable||"obj","_",i)}catch(a){throw a.source=i,a}var c=function(n){return o.call(this,n,m)},f=t.variable||"obj";return c.source="function("+f+"){\n"+i+"}",c},m.chain=function(n){var t=m(n);return t._chain=!0,t};var P=function(n,t){return n._chain?m(t).chain():t};m.mixin=function(n){m.each(m.functions(n),function(t){var r=m[t]=n[t];m.prototype[t]=function(){var n=[this._wrapped];return f.apply(n,arguments),P(this,r.apply(m,n))}})},m.mixin(m),m.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=o[n];m.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],P(this,r)}}),m.each(["concat","join","slice"],function(n){var t=o[n];m.prototype[n]=function(){return P(this,t.apply(this._wrapped,arguments))}}),m.prototype.value=function(){return this._wrapped},m.prototype.valueOf=m.prototype.toJSON=m.prototype.value,m.prototype.toString=function(){return""+this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return m})}).call(this);
-//# sourceMappingURL=underscore-min.map \ No newline at end of file
diff --git a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/underscore.js b/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/underscore.js
deleted file mode 100644
index bddfdc9f..00000000
--- a/ecomp-portal-FE/client/bower_components/lodash/vendor/underscore/underscore.js
+++ /dev/null
@@ -1,1620 +0,0 @@
-// Underscore.js 1.8.3
-// http://underscorejs.org
-// (c) 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
-// Underscore may be freely distributed under the MIT license.
-
-(function() {
-
- // Baseline setup
- // --------------
-
- // Establish the root object, `window` (`self`) in the browser, `global`
- // on the server, or `this` in some virtual machines. We use `self`
- // instead of `window` for `WebWorker` support.
- var root = typeof self == 'object' && self.self === self && self ||
- typeof global == 'object' && global.global === global && global ||
- this;
-
- // Save the previous value of the `_` variable.
- var previousUnderscore = root._;
-
- // Save bytes in the minified (but not gzipped) version:
- var ArrayProto = Array.prototype, ObjProto = Object.prototype;
- var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;
-
- // Create quick reference variables for speed access to core prototypes.
- var push = ArrayProto.push,
- slice = ArrayProto.slice,
- toString = ObjProto.toString,
- hasOwnProperty = ObjProto.hasOwnProperty;
-
- // All **ECMAScript 5** native function implementations that we hope to use
- // are declared here.
- var nativeIsArray = Array.isArray,
- nativeKeys = Object.keys,
- nativeCreate = Object.create;
-
- // Naked function reference for surrogate-prototype-swapping.
- var Ctor = function(){};
-
- // Create a safe reference to the Underscore object for use below.
- var _ = function(obj) {
- if (obj instanceof _) return obj;
- if (!(this instanceof _)) return new _(obj);
- this._wrapped = obj;
- };
-
- // Export the Underscore object for **Node.js**, with
- // backwards-compatibility for their old module API. If we're in
- // the browser, add `_` as a global object.
- // (`nodeType` is checked to ensure that `module`
- // and `exports` are not HTML elements.)
- if (typeof exports != 'undefined' && !exports.nodeType) {
- if (typeof module != 'undefined' && !module.nodeType && module.exports) {
- exports = module.exports = _;
- }
- exports._ = _;
- } else {
- root._ = _;
- }
-
- // Current version.
- _.VERSION = '1.8.3';
-
- // Internal function that returns an efficient (for current engines) version
- // of the passed-in callback, to be repeatedly applied in other Underscore
- // functions.
- var optimizeCb = function(func, context, argCount) {
- if (context === void 0) return func;
- switch (argCount == null ? 3 : argCount) {
- case 1: return function(value) {
- return func.call(context, value);
- };
- // The 2-parameter case has been omitted only because no current consumers
- // made use of it.
- case 3: return function(value, index, collection) {
- return func.call(context, value, index, collection);
- };
- case 4: return function(accumulator, value, index, collection) {
- return func.call(context, accumulator, value, index, collection);
- };
- }
- return function() {
- return func.apply(context, arguments);
- };
- };
-
- // An internal function to generate callbacks that can be applied to each
- // element in a collection, returning the desired result — either `identity`,
- // an arbitrary callback, a property matcher, or a property accessor.
- var cb = function(value, context, argCount) {
- if (value == null) return _.identity;
- if (_.isFunction(value)) return optimizeCb(value, context, argCount);
- if (_.isObject(value)) return _.matcher(value);
- return _.property(value);
- };
-
- // An external wrapper for the internal callback generator.
- _.iteratee = function(value, context) {
- return cb(value, context, Infinity);
- };
-
- // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html)
- // This accumulates the arguments passed into an array, after a given index.
- var restArgs = function(func, startIndex) {
- startIndex = startIndex == null ? func.length - 1 : +startIndex;
- return function() {
- var length = Math.max(arguments.length - startIndex, 0);
- var rest = Array(length);
- for (var index = 0; index < length; index++) {
- rest[index] = arguments[index + startIndex];
- }
- switch (startIndex) {
- case 0: return func.call(this, rest);
- case 1: return func.call(this, arguments[0], rest);
- case 2: return func.call(this, arguments[0], arguments[1], rest);
- }
- var args = Array(startIndex + 1);
- for (index = 0; index < startIndex; index++) {
- args[index] = arguments[index];
- }
- args[startIndex] = rest;
- return func.apply(this, args);
- };
- };
-
- // An internal function for creating a new object that inherits from another.
- var baseCreate = function(prototype) {
- if (!_.isObject(prototype)) return {};
- if (nativeCreate) return nativeCreate(prototype);
- Ctor.prototype = prototype;
- var result = new Ctor;
- Ctor.prototype = null;
- return result;
- };
-
- var property = function(key) {
- return function(obj) {
- return obj == null ? void 0 : obj[key];
- };
- };
-
- // Helper for collection methods to determine whether a collection
- // should be iterated as an array or as an object.
- // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
- // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
- var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
- var getLength = property('length');
- var isArrayLike = function(collection) {
- var length = getLength(collection);
- return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
- };
-
- // Collection Functions
- // --------------------
-
- // The cornerstone, an `each` implementation, aka `forEach`.
- // Handles raw objects in addition to array-likes. Treats all
- // sparse array-likes as if they were dense.
- _.each = _.forEach = function(obj, iteratee, context) {
- iteratee = optimizeCb(iteratee, context);
- var i, length;
- if (isArrayLike(obj)) {
- for (i = 0, length = obj.length; i < length; i++) {
- iteratee(obj[i], i, obj);
- }
- } else {
- var keys = _.keys(obj);
- for (i = 0, length = keys.length; i < length; i++) {
- iteratee(obj[keys[i]], keys[i], obj);
- }
- }
- return obj;
- };
-
- // Return the results of applying the iteratee to each element.
- _.map = _.collect = function(obj, iteratee, context) {
- iteratee = cb(iteratee, context);
- var keys = !isArrayLike(obj) && _.keys(obj),
- length = (keys || obj).length,
- results = Array(length);
- for (var index = 0; index < length; index++) {
- var currentKey = keys ? keys[index] : index;
- results[index] = iteratee(obj[currentKey], currentKey, obj);
- }
- return results;
- };
-
- // Create a reducing function iterating left or right.
- var createReduce = function(dir) {
- // Wrap code that reassigns argument variables in a separate function than
- // the one that accesses `arguments.length` to avoid a perf hit. (#1991)
- var reducer = function(obj, iteratee, memo, initial) {
- var keys = !isArrayLike(obj) && _.keys(obj),
- length = (keys || obj).length,
- index = dir > 0 ? 0 : length - 1;
- if (!initial) {
- memo = obj[keys ? keys[index] : index];
- index += dir;
- }
- for (; index >= 0 && index < length; index += dir) {
- var currentKey = keys ? keys[index] : index;
- memo = iteratee(memo, obj[currentKey], currentKey, obj);
- }
- return memo;
- };
-
- return function(obj, iteratee, memo, context) {
- var initial = arguments.length >= 3;
- return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);
- };
- };
-
- // **Reduce** builds up a single result from a list of values, aka `inject`,
- // or `foldl`.
- _.reduce = _.foldl = _.inject = createReduce(1);
-
- // The right-associative version of reduce, also known as `foldr`.
- _.reduceRight = _.foldr = createReduce(-1);
-
- // Return the first value which passes a truth test. Aliased as `detect`.
- _.find = _.detect = function(obj, predicate, context) {
- var keyFinder = isArrayLike(obj) ? _.findIndex : _.findKey;
- var key = keyFinder(obj, predicate, context);
- if (key !== void 0 && key !== -1) return obj[key];
- };
-
- // Return all the elements that pass a truth test.
- // Aliased as `select`.
- _.filter = _.select = function(obj, predicate, context) {
- var results = [];
- predicate = cb(predicate, context);
- _.each(obj, function(value, index, list) {
- if (predicate(value, index, list)) results.push(value);
- });
- return results;
- };
-
- // Return all the elements for which a truth test fails.
- _.reject = function(obj, predicate, context) {
- return _.filter(obj, _.negate(cb(predicate)), context);
- };
-
- // Determine whether all of the elements match a truth test.
- // Aliased as `all`.
- _.every = _.all = function(obj, predicate, context) {
- predicate = cb(predicate, context);
- var keys = !isArrayLike(obj) && _.keys(obj),
- length = (keys || obj).length;
- for (var index = 0; index < length; index++) {
- var currentKey = keys ? keys[index] : index;
- if (!predicate(obj[currentKey], currentKey, obj)) return false;
- }
- return true;
- };
-
- // Determine if at least one element in the object matches a truth test.
- // Aliased as `any`.
- _.some = _.any = function(obj, predicate, context) {
- predicate = cb(predicate, context);
- var keys = !isArrayLike(obj) && _.keys(obj),
- length = (keys || obj).length;
- for (var index = 0; index < length; index++) {
- var currentKey = keys ? keys[index] : index;
- if (predicate(obj[currentKey], currentKey, obj)) return true;
- }
- return false;
- };
-
- // Determine if the array or object contains a given item (using `===`).
- // Aliased as `includes` and `include`.
- _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
- if (!isArrayLike(obj)) obj = _.values(obj);
- if (typeof fromIndex != 'number' || guard) fromIndex = 0;
- return _.indexOf(obj, item, fromIndex) >= 0;
- };
-
- // Invoke a method (with arguments) on every item in a collection.
- _.invoke = restArgs(function(obj, method, args) {
- var isFunc = _.isFunction(method);
- return _.map(obj, function(value) {
- var func = isFunc ? method : value[method];
- return func == null ? func : func.apply(value, args);
- });
- });
-
- // Convenience version of a common use case of `map`: fetching a property.
- _.pluck = function(obj, key) {
- return _.map(obj, _.property(key));
- };
-
- // Convenience version of a common use case of `filter`: selecting only objects
- // containing specific `key:value` pairs.
- _.where = function(obj, attrs) {
- return _.filter(obj, _.matcher(attrs));
- };
-
- // Convenience version of a common use case of `find`: getting the first object
- // containing specific `key:value` pairs.
- _.findWhere = function(obj, attrs) {
- return _.find(obj, _.matcher(attrs));
- };
-
- // Return the maximum element (or element-based computation).
- _.max = function(obj, iteratee, context) {
- var result = -Infinity, lastComputed = -Infinity,
- value, computed;
- if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object') && obj != null) {
- obj = isArrayLike(obj) ? obj : _.values(obj);
- for (var i = 0, length = obj.length; i < length; i++) {
- value = obj[i];
- if (value != null && value > result) {
- result = value;
- }
- }
- } else {
- iteratee = cb(iteratee, context);
- _.each(obj, function(v, index, list) {
- computed = iteratee(v, index, list);
- if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
- result = v;
- lastComputed = computed;
- }
- });
- }
- return result;
- };
-
- // Return the minimum element (or element-based computation).
- _.min = function(obj, iteratee, context) {
- var result = Infinity, lastComputed = Infinity,
- value, computed;
- if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object') && obj != null) {
- obj = isArrayLike(obj) ? obj : _.values(obj);
- for (var i = 0, length = obj.length; i < length; i++) {
- value = obj[i];
- if (value != null && value < result) {
- result = value;
- }
- }
- } else {
- iteratee = cb(iteratee, context);
- _.each(obj, function(v, index, list) {
- computed = iteratee(v, index, list);
- if (computed < lastComputed || computed === Infinity && result === Infinity) {
- result = v;
- lastComputed = computed;
- }
- });
- }
- return result;
- };
-
- // Shuffle a collection.
- _.shuffle = function(obj) {
- return _.sample(obj, Infinity);
- };
-
- // Sample **n** random values from a collection using the modern version of the
- // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
- // If **n** is not specified, returns a single random element.
- // The internal `guard` argument allows it to work with `map`.
- _.sample = function(obj, n, guard) {
- if (n == null || guard) {
- if (!isArrayLike(obj)) obj = _.values(obj);
- return obj[_.random(obj.length - 1)];
- }
- var sample = isArrayLike(obj) ? _.clone(obj) : _.values(obj);
- var length = getLength(sample);
- n = Math.max(Math.min(n, length), 0);
- var last = length - 1;
- for (var index = 0; index < n; index++) {
- var rand = _.random(index, last);
- var temp = sample[index];
- sample[index] = sample[rand];
- sample[rand] = temp;
- }
- return sample.slice(0, n);
- };
-
- // Sort the object's values by a criterion produced by an iteratee.
- _.sortBy = function(obj, iteratee, context) {
- var index = 0;
- iteratee = cb(iteratee, context);
- return _.pluck(_.map(obj, function(value, key, list) {
- return {
- value: value,
- index: index++,
- criteria: iteratee(value, key, list)
- };
- }).sort(function(left, right) {
- var a = left.criteria;
- var b = right.criteria;
- if (a !== b) {
- if (a > b || a === void 0) return 1;
- if (a < b || b === void 0) return -1;
- }
- return left.index - right.index;
- }), 'value');
- };
-
- // An internal function used for aggregate "group by" operations.
- var group = function(behavior, partition) {
- return function(obj, iteratee, context) {
- var result = partition ? [[], []] : {};
- iteratee = cb(iteratee, context);
- _.each(obj, function(value, index) {
- var key = iteratee(value, index, obj);
- behavior(result, value, key);
- });
- return result;
- };
- };
-
- // Groups the object's values by a criterion. Pass either a string attribute
- // to group by, or a function that returns the criterion.
- _.groupBy = group(function(result, value, key) {
- if (_.has(result, key)) result[key].push(value); else result[key] = [value];
- });
-
- // Indexes the object's values by a criterion, similar to `groupBy`, but for
- // when you know that your index values will be unique.
- _.indexBy = group(function(result, value, key) {
- result[key] = value;
- });
-
- // Counts instances of an object that group by a certain criterion. Pass
- // either a string attribute to count by, or a function that returns the
- // criterion.
- _.countBy = group(function(result, value, key) {
- if (_.has(result, key)) result[key]++; else result[key] = 1;
- });
-
- var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;
- // Safely create a real, live array from anything iterable.
- _.toArray = function(obj) {
- if (!obj) return [];
- if (_.isArray(obj)) return slice.call(obj);
- if (_.isString(obj)) {
- // Keep surrogate pair characters together
- return obj.match(reStrSymbol);
- }
- if (isArrayLike(obj)) return _.map(obj);
- return _.values(obj);
- };
-
- // Return the number of elements in an object.
- _.size = function(obj) {
- if (obj == null) return 0;
- return isArrayLike(obj) ? obj.length : _.keys(obj).length;
- };
-
- // Split a collection into two arrays: one whose elements all satisfy the given
- // predicate, and one whose elements all do not satisfy the predicate.
- _.partition = group(function(result, value, pass) {
- result[pass ? 0 : 1].push(value);
- }, true);
-
- // Array Functions
- // ---------------
-
- // Get the first element of an array. Passing **n** will return the first N
- // values in the array. Aliased as `head` and `take`. The **guard** check
- // allows it to work with `_.map`.
- _.first = _.head = _.take = function(array, n, guard) {
- if (array == null) return void 0;
- if (n == null || guard) return array[0];
- return _.initial(array, array.length - n);
- };
-
- // Returns everything but the last entry of the array. Especially useful on
- // the arguments object. Passing **n** will return all the values in
- // the array, excluding the last N.
- _.initial = function(array, n, guard) {
- return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
- };
-
- // Get the last element of an array. Passing **n** will return the last N
- // values in the array.
- _.last = function(array, n, guard) {
- if (array == null) return void 0;
- if (n == null || guard) return array[array.length - 1];
- return _.rest(array, Math.max(0, array.length - n));
- };
-
- // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
- // Especially useful on the arguments object. Passing an **n** will return
- // the rest N values in the array.
- _.rest = _.tail = _.drop = function(array, n, guard) {
- return slice.call(array, n == null || guard ? 1 : n);
- };
-
- // Trim out all falsy values from an array.
- _.compact = function(array) {
- return _.filter(array);
- };
-
- // Internal implementation of a recursive `flatten` function.
- var flatten = function(input, shallow, strict, output) {
- output = output || [];
- var idx = output.length;
- for (var i = 0, length = getLength(input); i < length; i++) {
- var value = input[i];
- if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
- // Flatten current level of array or arguments object.
- if (shallow) {
- var j = 0, len = value.length;
- while (j < len) output[idx++] = value[j++];
- } else {
- flatten(value, shallow, strict, output);
- idx = output.length;
- }
- } else if (!strict) {
- output[idx++] = value;
- }
- }
- return output;
- };
-
- // Flatten out an array, either recursively (by default), or just one level.
- _.flatten = function(array, shallow) {
- return flatten(array, shallow, false);
- };
-
- // Return a version of the array that does not contain the specified value(s).
- _.without = restArgs(function(array, otherArrays) {
- return _.difference(array, otherArrays);
- });
-
- // Produce a duplicate-free version of the array. If the array has already
- // been sorted, you have the option of using a faster algorithm.
- // Aliased as `unique`.
- _.uniq = _.unique = function(array, isSorted, iteratee, context) {
- if (!_.isBoolean(isSorted)) {
- context = iteratee;
- iteratee = isSorted;
- isSorted = false;
- }
- if (iteratee != null) iteratee = cb(iteratee, context);
- var result = [];
- var seen = [];
- for (var i = 0, length = getLength(array); i < length; i++) {
- var value = array[i],
- computed = iteratee ? iteratee(value, i, array) : value;
- if (isSorted) {
- if (!i || seen !== computed) result.push(value);
- seen = computed;
- } else if (iteratee) {
- if (!_.contains(seen, computed)) {
- seen.push(computed);
- result.push(value);
- }
- } else if (!_.contains(result, value)) {
- result.push(value);
- }
- }
- return result;
- };
-
- // Produce an array that contains the union: each distinct element from all of
- // the passed-in arrays.
- _.union = restArgs(function(arrays) {
- return _.uniq(flatten(arrays, true, true));
- });
-
- // Produce an array that contains every item shared between all the
- // passed-in arrays.
- _.intersection = function(array) {
- var result = [];
- var argsLength = arguments.length;
- for (var i = 0, length = getLength(array); i < length; i++) {
- var item = array[i];
- if (_.contains(result, item)) continue;
- var j;
- for (j = 1; j < argsLength; j++) {
- if (!_.contains(arguments[j], item)) break;
- }
- if (j === argsLength) result.push(item);
- }
- return result;
- };
-
- // Take the difference between one array and a number of other arrays.
- // Only the elements present in just the first array will remain.
- _.difference = restArgs(function(array, rest) {
- rest = flatten(rest, true, true);
- return _.filter(array, function(value){
- return !_.contains(rest, value);
- });
- });
-
- // Complement of _.zip. Unzip accepts an array of arrays and groups
- // each array's elements on shared indices.
- _.unzip = function(array) {
- var length = array && _.max(array, getLength).length || 0;
- var result = Array(length);
-
- for (var index = 0; index < length; index++) {
- result[index] = _.pluck(array, index);
- }
- return result;
- };
-
- // Zip together multiple lists into a single array -- elements that share
- // an index go together.
- _.zip = restArgs(_.unzip);
-
- // Converts lists into objects. Pass either a single array of `[key, value]`
- // pairs, or two parallel arrays of the same length -- one of keys, and one of
- // the corresponding values.
- _.object = function(list, values) {
- var result = {};
- for (var i = 0, length = getLength(list); i < length; i++) {
- if (values) {
- result[list[i]] = values[i];
- } else {
- result[list[i][0]] = list[i][1];
- }
- }
- return result;
- };
-
- // Generator function to create the findIndex and findLastIndex functions.
- var createPredicateIndexFinder = function(dir) {
- return function(array, predicate, context) {
- predicate = cb(predicate, context);
- var length = getLength(array);
- var index = dir > 0 ? 0 : length - 1;
- for (; index >= 0 && index < length; index += dir) {
- if (predicate(array[index], index, array)) return index;
- }
- return -1;
- };
- };
-
- // Returns the first index on an array-like that passes a predicate test.
- _.findIndex = createPredicateIndexFinder(1);
- _.findLastIndex = createPredicateIndexFinder(-1);
-
- // Use a comparator function to figure out the smallest index at which
- // an object should be inserted so as to maintain order. Uses binary search.
- _.sortedIndex = function(array, obj, iteratee, context) {
- iteratee = cb(iteratee, context, 1);
- var value = iteratee(obj);
- var low = 0, high = getLength(array);
- while (low < high) {
- var mid = Math.floor((low + high) / 2);
- if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
- }
- return low;
- };
-
- // Generator function to create the indexOf and lastIndexOf functions.
- var createIndexFinder = function(dir, predicateFind, sortedIndex) {
- return function(array, item, idx) {
- var i = 0, length = getLength(array);
- if (typeof idx == 'number') {
- if (dir > 0) {
- i = idx >= 0 ? idx : Math.max(idx + length, i);
- } else {
- length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
- }
- } else if (sortedIndex && idx && length) {
- idx = sortedIndex(array, item);
- return array[idx] === item ? idx : -1;
- }
- if (item !== item) {
- idx = predicateFind(slice.call(array, i, length), _.isNaN);
- return idx >= 0 ? idx + i : -1;
- }
- for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
- if (array[idx] === item) return idx;
- }
- return -1;
- };
- };
-
- // Return the position of the first occurrence of an item in an array,
- // or -1 if the item is not included in the array.
- // If the array is large and already in sort order, pass `true`
- // for **isSorted** to use binary search.
- _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
- _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
-
- // Generate an integer Array containing an arithmetic progression. A port of
- // the native Python `range()` function. See
- // [the Python documentation](http://docs.python.org/library/functions.html#range).
- _.range = function(start, stop, step) {
- if (stop == null) {
- stop = start || 0;
- start = 0;
- }
- if (!step) {
- step = stop < start ? -1 : 1;
- }
-
- var length = Math.max(Math.ceil((stop - start) / step), 0);
- var range = Array(length);
-
- for (var idx = 0; idx < length; idx++, start += step) {
- range[idx] = start;
- }
-
- return range;
- };
-
- // Split an **array** into several arrays containing **count** or less elements
- // of initial array.
- _.chunk = function(array, count) {
- if (count == null || count < 1) return [];
-
- var result = [];
- var i = 0, length = array.length;
- while (i < length) {
- result.push(slice.call(array, i, i += count));
- }
- return result;
- };
-
- // Function (ahem) Functions
- // ------------------
-
- // Determines whether to execute a function as a constructor
- // or a normal function with the provided arguments.
- var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
- if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
- var self = baseCreate(sourceFunc.prototype);
- var result = sourceFunc.apply(self, args);
- if (_.isObject(result)) return result;
- return self;
- };
-
- // Create a function bound to a given object (assigning `this`, and arguments,
- // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
- // available.
- _.bind = restArgs(function(func, context, args) {
- if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
- var bound = restArgs(function(callArgs) {
- return executeBound(func, bound, context, this, args.concat(callArgs));
- });
- return bound;
- });
-
- // Partially apply a function by creating a version that has had some of its
- // arguments pre-filled, without changing its dynamic `this` context. _ acts
- // as a placeholder by default, allowing any combination of arguments to be
- // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.
- _.partial = restArgs(function(func, boundArgs) {
- var placeholder = _.partial.placeholder;
- var bound = function() {
- var position = 0, length = boundArgs.length;
- var args = Array(length);
- for (var i = 0; i < length; i++) {
- args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];
- }
- while (position < arguments.length) args.push(arguments[position++]);
- return executeBound(func, bound, this, this, args);
- };
- return bound;
- });
-
- _.partial.placeholder = _;
-
- // Bind a number of an object's methods to that object. Remaining arguments
- // are the method names to be bound. Useful for ensuring that all callbacks
- // defined on an object belong to it.
- _.bindAll = restArgs(function(obj, keys) {
- keys = flatten(keys, false, false);
- var index = keys.length;
- if (index < 1) throw new Error('bindAll must be passed function names');
- while (index--) {
- var key = keys[index];
- obj[key] = _.bind(obj[key], obj);
- }
- });
-
- // Memoize an expensive function by storing its results.
- _.memoize = function(func, hasher) {
- var memoize = function(key) {
- var cache = memoize.cache;
- var address = '' + (hasher ? hasher.apply(this, arguments) : key);
- if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
- return cache[address];
- };
- memoize.cache = {};
- return memoize;
- };
-
- // Delays a function for the given number of milliseconds, and then calls
- // it with the arguments supplied.
- _.delay = restArgs(function(func, wait, args) {
- return setTimeout(function() {
- return func.apply(null, args);
- }, wait);
- });
-
- // Defers a function, scheduling it to run after the current call stack has
- // cleared.
- _.defer = _.partial(_.delay, _, 1);
-
- // Returns a function, that, when invoked, will only be triggered at most once
- // during a given window of time. Normally, the throttled function will run
- // as much as it can, without ever going more than once per `wait` duration;
- // but if you'd like to disable the execution on the leading edge, pass
- // `{leading: false}`. To disable execution on the trailing edge, ditto.
- _.throttle = function(func, wait, options) {
- var timeout, context, args, result;
- var previous = 0;
- if (!options) options = {};
-
- var later = function() {
- previous = options.leading === false ? 0 : _.now();
- timeout = null;
- result = func.apply(context, args);
- if (!timeout) context = args = null;
- };
-
- var throttled = function() {
- var now = _.now();
- if (!previous && options.leading === false) previous = now;
- var remaining = wait - (now - previous);
- context = this;
- args = arguments;
- if (remaining <= 0 || remaining > wait) {
- if (timeout) {
- clearTimeout(timeout);
- timeout = null;
- }
- previous = now;
- result = func.apply(context, args);
- if (!timeout) context = args = null;
- } else if (!timeout && options.trailing !== false) {
- timeout = setTimeout(later, remaining);
- }
- return result;
- };
-
- throttled.cancel = function() {
- clearTimeout(timeout);
- previous = 0;
- timeout = context = args = null;
- };
-
- return throttled;
- };
-
- // Returns a function, that, as long as it continues to be invoked, will not
- // be triggered. The function will be called after it stops being called for
- // N milliseconds. If `immediate` is passed, trigger the function on the
- // leading edge, instead of the trailing.
- _.debounce = function(func, wait, immediate) {
- var timeout, result;
-
- var later = function(context, args) {
- timeout = null;
- if (args) result = func.apply(context, args);
- };
-
- var debounced = restArgs(function(args) {
- if (timeout) clearTimeout(timeout);
- if (immediate) {
- var callNow = !timeout;
- timeout = setTimeout(later, wait);
- if (callNow) result = func.apply(this, args);
- } else {
- timeout = _.delay(later, wait, this, args);
- }
-
- return result;
- });
-
- debounced.cancel = function() {
- clearTimeout(timeout);
- timeout = null;
- };
-
- return debounced;
- };
-
- // Returns the first function passed as an argument to the second,
- // allowing you to adjust arguments, run code before and after, and
- // conditionally execute the original function.
- _.wrap = function(func, wrapper) {
- return _.partial(wrapper, func);
- };
-
- // Returns a negated version of the passed-in predicate.
- _.negate = function(predicate) {
- return function() {
- return !predicate.apply(this, arguments);
- };
- };
-
- // Returns a function that is the composition of a list of functions, each
- // consuming the return value of the function that follows.
- _.compose = function() {
- var args = arguments;
- var start = args.length - 1;
- return function() {
- var i = start;
- var result = args[start].apply(this, arguments);
- while (i--) result = args[i].call(this, result);
- return result;
- };
- };
-
- // Returns a function that will only be executed on and after the Nth call.
- _.after = function(times, func) {
- return function() {
- if (--times < 1) {
- return func.apply(this, arguments);
- }
- };
- };
-
- // Returns a function that will only be executed up to (but not including) the Nth call.
- _.before = function(times, func) {
- var memo;
- return function() {
- if (--times > 0) {
- memo = func.apply(this, arguments);
- }
- if (times <= 1) func = null;
- return memo;
- };
- };
-
- // Returns a function that will be executed at most one time, no matter how
- // often you call it. Useful for lazy initialization.
- _.once = _.partial(_.before, 2);
-
- _.restArgs = restArgs;
-
- // Object Functions
- // ----------------
-
- // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
- var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
- var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
- 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
-
- var collectNonEnumProps = function(obj, keys) {
- var nonEnumIdx = nonEnumerableProps.length;
- var constructor = obj.constructor;
- var proto = _.isFunction(constructor) && constructor.prototype || ObjProto;
-
- // Constructor is a special case.
- var prop = 'constructor';
- if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
-
- while (nonEnumIdx--) {
- prop = nonEnumerableProps[nonEnumIdx];
- if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
- keys.push(prop);
- }
- }
- };
-
- // Retrieve the names of an object's own properties.
- // Delegates to **ECMAScript 5**'s native `Object.keys`.
- _.keys = function(obj) {
- if (!_.isObject(obj)) return [];
- if (nativeKeys) return nativeKeys(obj);
- var keys = [];
- for (var key in obj) if (_.has(obj, key)) keys.push(key);
- // Ahem, IE < 9.
- if (hasEnumBug) collectNonEnumProps(obj, keys);
- return keys;
- };
-
- // Retrieve all the property names of an object.
- _.allKeys = function(obj) {
- if (!_.isObject(obj)) return [];
- var keys = [];
- for (var key in obj) keys.push(key);
- // Ahem, IE < 9.
- if (hasEnumBug) collectNonEnumProps(obj, keys);
- return keys;
- };
-
- // Retrieve the values of an object's properties.
- _.values = function(obj) {
- var keys = _.keys(obj);
- var length = keys.length;
- var values = Array(length);
- for (var i = 0; i < length; i++) {
- values[i] = obj[keys[i]];
- }
- return values;
- };
-
- // Returns the results of applying the iteratee to each element of the object.
- // In contrast to _.map it returns an object.
- _.mapObject = function(obj, iteratee, context) {
- iteratee = cb(iteratee, context);
- var keys = _.keys(obj),
- length = keys.length,
- results = {};
- for (var index = 0; index < length; index++) {
- var currentKey = keys[index];
- results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
- }
- return results;
- };
-
- // Convert an object into a list of `[key, value]` pairs.
- _.pairs = function(obj) {
- var keys = _.keys(obj);
- var length = keys.length;
- var pairs = Array(length);
- for (var i = 0; i < length; i++) {
- pairs[i] = [keys[i], obj[keys[i]]];
- }
- return pairs;
- };
-
- // Invert the keys and values of an object. The values must be serializable.
- _.invert = function(obj) {
- var result = {};
- var keys = _.keys(obj);
- for (var i = 0, length = keys.length; i < length; i++) {
- result[obj[keys[i]]] = keys[i];
- }
- return result;
- };
-
- // Return a sorted list of the function names available on the object.
- // Aliased as `methods`.
- _.functions = _.methods = function(obj) {
- var names = [];
- for (var key in obj) {
- if (_.isFunction(obj[key])) names.push(key);
- }
- return names.sort();
- };
-
- // An internal function for creating assigner functions.
- var createAssigner = function(keysFunc, defaults) {
- return function(obj) {
- var length = arguments.length;
- if (defaults) obj = Object(obj);
- if (length < 2 || obj == null) return obj;
- for (var index = 1; index < length; index++) {
- var source = arguments[index],
- keys = keysFunc(source),
- l = keys.length;
- for (var i = 0; i < l; i++) {
- var key = keys[i];
- if (!defaults || obj[key] === void 0) obj[key] = source[key];
- }
- }
- return obj;
- };
- };
-
- // Extend a given object with all the properties in passed-in object(s).
- _.extend = createAssigner(_.allKeys);
-
- // Assigns a given object with all the own properties in the passed-in object(s).
- // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
- _.extendOwn = _.assign = createAssigner(_.keys);
-
- // Returns the first key on an object that passes a predicate test.
- _.findKey = function(obj, predicate, context) {
- predicate = cb(predicate, context);
- var keys = _.keys(obj), key;
- for (var i = 0, length = keys.length; i < length; i++) {
- key = keys[i];
- if (predicate(obj[key], key, obj)) return key;
- }
- };
-
- // Internal pick helper function to determine if `obj` has key `key`.
- var keyInObj = function(value, key, obj) {
- return key in obj;
- };
-
- // Return a copy of the object only containing the whitelisted properties.
- _.pick = restArgs(function(obj, keys) {
- var result = {}, iteratee = keys[0];
- if (obj == null) return result;
- if (_.isFunction(iteratee)) {
- if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);
- keys = _.allKeys(obj);
- } else {
- iteratee = keyInObj;
- keys = flatten(keys, false, false);
- obj = Object(obj);
- }
- for (var i = 0, length = keys.length; i < length; i++) {
- var key = keys[i];
- var value = obj[key];
- if (iteratee(value, key, obj)) result[key] = value;
- }
- return result;
- });
-
- // Return a copy of the object without the blacklisted properties.
- _.omit = restArgs(function(obj, keys) {
- var iteratee = keys[0], context;
- if (_.isFunction(iteratee)) {
- iteratee = _.negate(iteratee);
- if (keys.length > 1) context = keys[1];
- } else {
- keys = _.map(flatten(keys, false, false), String);
- iteratee = function(value, key) {
- return !_.contains(keys, key);
- };
- }
- return _.pick(obj, iteratee, context);
- });
-
- // Fill in a given object with default properties.
- _.defaults = createAssigner(_.allKeys, true);
-
- // Creates an object that inherits from the given prototype object.
- // If additional properties are provided then they will be added to the
- // created object.
- _.create = function(prototype, props) {
- var result = baseCreate(prototype);
- if (props) _.extendOwn(result, props);
- return result;
- };
-
- // Create a (shallow-cloned) duplicate of an object.
- _.clone = function(obj) {
- if (!_.isObject(obj)) return obj;
- return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
- };
-
- // Invokes interceptor with the obj, and then returns obj.
- // The primary purpose of this method is to "tap into" a method chain, in
- // order to perform operations on intermediate results within the chain.
- _.tap = function(obj, interceptor) {
- interceptor(obj);
- return obj;
- };
-
- // Returns whether an object has a given set of `key:value` pairs.
- _.isMatch = function(object, attrs) {
- var keys = _.keys(attrs), length = keys.length;
- if (object == null) return !length;
- var obj = Object(object);
- for (var i = 0; i < length; i++) {
- var key = keys[i];
- if (attrs[key] !== obj[key] || !(key in obj)) return false;
- }
- return true;
- };
-
-
- // Internal recursive comparison function for `isEqual`.
- var eq, deepEq;
- eq = function(a, b, aStack, bStack) {
- // Identical objects are equal. `0 === -0`, but they aren't identical.
- // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
- if (a === b) return a !== 0 || 1 / a === 1 / b;
- // A strict comparison is necessary because `null == undefined`.
- if (a == null || b == null) return a === b;
- // `NaN`s are equivalent, but non-reflexive.
- if (a !== a) return b !== b;
- // Exhaust primitive checks
- var type = typeof a;
- if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;
- return deepEq(a, b, aStack, bStack);
- };
-
- // Internal recursive comparison function for `isEqual`.
- deepEq = function(a, b, aStack, bStack) {
- // Unwrap any wrapped objects.
- if (a instanceof _) a = a._wrapped;
- if (b instanceof _) b = b._wrapped;
- // Compare `[[Class]]` names.
- var className = toString.call(a);
- if (className !== toString.call(b)) return false;
- switch (className) {
- // Strings, numbers, regular expressions, dates, and booleans are compared by value.
- case '[object RegExp]':
- // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
- case '[object String]':
- // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
- // equivalent to `new String("5")`.
- return '' + a === '' + b;
- case '[object Number]':
- // `NaN`s are equivalent, but non-reflexive.
- // Object(NaN) is equivalent to NaN.
- if (+a !== +a) return +b !== +b;
- // An `egal` comparison is performed for other numeric values.
- return +a === 0 ? 1 / +a === 1 / b : +a === +b;
- case '[object Date]':
- case '[object Boolean]':
- // Coerce dates and booleans to numeric primitive values. Dates are compared by their
- // millisecond representations. Note that invalid dates with millisecond representations
- // of `NaN` are not equivalent.
- return +a === +b;
- case '[object Symbol]':
- return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);
- }
-
- var areArrays = className === '[object Array]';
- if (!areArrays) {
- if (typeof a != 'object' || typeof b != 'object') return false;
-
- // Objects with different constructors are not equivalent, but `Object`s or `Array`s
- // from different frames are.
- var aCtor = a.constructor, bCtor = b.constructor;
- if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
- _.isFunction(bCtor) && bCtor instanceof bCtor)
- && ('constructor' in a && 'constructor' in b)) {
- return false;
- }
- }
- // Assume equality for cyclic structures. The algorithm for detecting cyclic
- // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
-
- // Initializing stack of traversed objects.
- // It's done here since we only need them for objects and arrays comparison.
- aStack = aStack || [];
- bStack = bStack || [];
- var length = aStack.length;
- while (length--) {
- // Linear search. Performance is inversely proportional to the number of
- // unique nested structures.
- if (aStack[length] === a) return bStack[length] === b;
- }
-
- // Add the first object to the stack of traversed objects.
- aStack.push(a);
- bStack.push(b);
-
- // Recursively compare objects and arrays.
- if (areArrays) {
- // Compare array lengths to determine if a deep comparison is necessary.
- length = a.length;
- if (length !== b.length) return false;
- // Deep compare the contents, ignoring non-numeric properties.
- while (length--) {
- if (!eq(a[length], b[length], aStack, bStack)) return false;
- }
- } else {
- // Deep compare objects.
- var keys = _.keys(a), key;
- length = keys.length;
- // Ensure that both objects contain the same number of properties before comparing deep equality.
- if (_.keys(b).length !== length) return false;
- while (length--) {
- // Deep compare each member
- key = keys[length];
- if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
- }
- }
- // Remove the first object from the stack of traversed objects.
- aStack.pop();
- bStack.pop();
- return true;
- };
-
- // Perform a deep comparison to check if two objects are equal.
- _.isEqual = function(a, b) {
- return eq(a, b);
- };
-
- // Is a given array, string, or object empty?
- // An "empty" object has no enumerable own-properties.
- _.isEmpty = function(obj) {
- if (obj == null) return true;
- if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
- return _.keys(obj).length === 0;
- };
-
- // Is a given value a DOM element?
- _.isElement = function(obj) {
- return !!(obj && obj.nodeType === 1);
- };
-
- // Is a given value an array?
- // Delegates to ECMA5's native Array.isArray
- _.isArray = nativeIsArray || function(obj) {
- return toString.call(obj) === '[object Array]';
- };
-
- // Is a given variable an object?
- _.isObject = function(obj) {
- var type = typeof obj;
- return type === 'function' || type === 'object' && !!obj;
- };
-
- // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError, isMap, isWeakMap, isSet, isWeakSet.
- _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error', 'Symbol', 'Map', 'WeakMap', 'Set', 'WeakSet'], function(name) {
- _['is' + name] = function(obj) {
- return toString.call(obj) === '[object ' + name + ']';
- };
- });
-
- // Define a fallback version of the method in browsers (ahem, IE < 9), where
- // there isn't any inspectable "Arguments" type.
- if (!_.isArguments(arguments)) {
- _.isArguments = function(obj) {
- return _.has(obj, 'callee');
- };
- }
-
- // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
- // IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).
- var nodelist = root.document && root.document.childNodes;
- if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {
- _.isFunction = function(obj) {
- return typeof obj == 'function' || false;
- };
- }
-
- // Is a given object a finite number?
- _.isFinite = function(obj) {
- return !_.isSymbol(obj) && isFinite(obj) && !isNaN(parseFloat(obj));
- };
-
- // Is the given value `NaN`?
- _.isNaN = function(obj) {
- return _.isNumber(obj) && isNaN(obj);
- };
-
- // Is a given value a boolean?
- _.isBoolean = function(obj) {
- return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
- };
-
- // Is a given value equal to null?
- _.isNull = function(obj) {
- return obj === null;
- };
-
- // Is a given variable undefined?
- _.isUndefined = function(obj) {
- return obj === void 0;
- };
-
- // Shortcut function for checking if an object has a given property directly
- // on itself (in other words, not on a prototype).
- _.has = function(obj, key) {
- return obj != null && hasOwnProperty.call(obj, key);
- };
-
- // Utility Functions
- // -----------------
-
- // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
- // previous owner. Returns a reference to the Underscore object.
- _.noConflict = function() {
- root._ = previousUnderscore;
- return this;
- };
-
- // Keep the identity function around for default iteratees.
- _.identity = function(value) {
- return value;
- };
-
- // Predicate-generating functions. Often useful outside of Underscore.
- _.constant = function(value) {
- return function() {
- return value;
- };
- };
-
- _.noop = function(){};
-
- _.property = property;
-
- // Generates a function for a given object that returns a given property.
- _.propertyOf = function(obj) {
- return obj == null ? function(){} : function(key) {
- return obj[key];
- };
- };
-
- // Returns a predicate for checking whether an object has a given set of
- // `key:value` pairs.
- _.matcher = _.matches = function(attrs) {
- attrs = _.extendOwn({}, attrs);
- return function(obj) {
- return _.isMatch(obj, attrs);
- };
- };
-
- // Run a function **n** times.
- _.times = function(n, iteratee, context) {
- var accum = Array(Math.max(0, n));
- iteratee = optimizeCb(iteratee, context, 1);
- for (var i = 0; i < n; i++) accum[i] = iteratee(i);
- return accum;
- };
-
- // Return a random integer between min and max (inclusive).
- _.random = function(min, max) {
- if (max == null) {
- max = min;
- min = 0;
- }
- return min + Math.floor(Math.random() * (max - min + 1));
- };
-
- // A (possibly faster) way to get the current timestamp as an integer.
- _.now = Date.now || function() {
- return new Date().getTime();
- };
-
- // List of HTML entities for escaping.
- var escapeMap = {
- '&': '&amp;',
- '<': '&lt;',
- '>': '&gt;',
- '"': '&quot;',
- "'": '&#x27;',
- '`': '&#x60;'
- };
- var unescapeMap = _.invert(escapeMap);
-
- // Functions for escaping and unescaping strings to/from HTML interpolation.
- var createEscaper = function(map) {
- var escaper = function(match) {
- return map[match];
- };
- // Regexes for identifying a key that needs to be escaped.
- var source = '(?:' + _.keys(map).join('|') + ')';
- var testRegexp = RegExp(source);
- var replaceRegexp = RegExp(source, 'g');
- return function(string) {
- string = string == null ? '' : '' + string;
- return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
- };
- };
- _.escape = createEscaper(escapeMap);
- _.unescape = createEscaper(unescapeMap);
-
- // If the value of the named `property` is a function then invoke it with the
- // `object` as context; otherwise, return it.
- _.result = function(object, prop, fallback) {
- var value = object == null ? void 0 : object[prop];
- if (value === void 0) {
- value = fallback;
- }
- return _.isFunction(value) ? value.call(object) : value;
- };
-
- // Generate a unique integer id (unique within the entire client session).
- // Useful for temporary DOM ids.
- var idCounter = 0;
- _.uniqueId = function(prefix) {
- var id = ++idCounter + '';
- return prefix ? prefix + id : id;
- };
-
- // By default, Underscore uses ERB-style template delimiters, change the
- // following template settings to use alternative delimiters.
- _.templateSettings = {
- evaluate: /<%([\s\S]+?)%>/g,
- interpolate: /<%=([\s\S]+?)%>/g,
- escape: /<%-([\s\S]+?)%>/g
- };
-
- // When customizing `templateSettings`, if you don't want to define an
- // interpolation, evaluation or escaping regex, we need one that is
- // guaranteed not to match.
- var noMatch = /(.)^/;
-
- // Certain characters need to be escaped so that they can be put into a
- // string literal.
- var escapes = {
- "'": "'",
- '\\': '\\',
- '\r': 'r',
- '\n': 'n',
- '\u2028': 'u2028',
- '\u2029': 'u2029'
- };
-
- var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
-
- var escapeChar = function(match) {
- return '\\' + escapes[match];
- };
-
- // JavaScript micro-templating, similar to John Resig's implementation.
- // Underscore templating handles arbitrary delimiters, preserves whitespace,
- // and correctly escapes quotes within interpolated code.
- // NB: `oldSettings` only exists for backwards compatibility.
- _.template = function(text, settings, oldSettings) {
- if (!settings && oldSettings) settings = oldSettings;
- settings = _.defaults({}, settings, _.templateSettings);
-
- // Combine delimiters into one regular expression via alternation.
- var matcher = RegExp([
- (settings.escape || noMatch).source,
- (settings.interpolate || noMatch).source,
- (settings.evaluate || noMatch).source
- ].join('|') + '|$', 'g');
-
- // Compile the template source, escaping string literals appropriately.
- var index = 0;
- var source = "__p+='";
- text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
- source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
- index = offset + match.length;
-
- if (escape) {
- source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
- } else if (interpolate) {
- source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
- } else if (evaluate) {
- source += "';\n" + evaluate + "\n__p+='";
- }
-
- // Adobe VMs need the match returned to produce the correct offset.
- return match;
- });
- source += "';\n";
-
- // If a variable is not specified, place data values in local scope.
- if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
-
- source = "var __t,__p='',__j=Array.prototype.join," +
- "print=function(){__p+=__j.call(arguments,'');};\n" +
- source + 'return __p;\n';
-
- var render;
- try {
- render = new Function(settings.variable || 'obj', '_', source);
- } catch (e) {
- e.source = source;
- throw e;
- }
-
- var template = function(data) {
- return render.call(this, data, _);
- };
-
- // Provide the compiled source as a convenience for precompilation.
- var argument = settings.variable || 'obj';
- template.source = 'function(' + argument + '){\n' + source + '}';
-
- return template;
- };
-
- // Add a "chain" function. Start chaining a wrapped Underscore object.
- _.chain = function(obj) {
- var instance = _(obj);
- instance._chain = true;
- return instance;
- };
-
- // OOP
- // ---------------
- // If Underscore is called as a function, it returns a wrapped object that
- // can be used OO-style. This wrapper holds altered versions of all the
- // underscore functions. Wrapped objects may be chained.
-
- // Helper function to continue chaining intermediate results.
- var chainResult = function(instance, obj) {
- return instance._chain ? _(obj).chain() : obj;
- };
-
- // Add your own custom functions to the Underscore object.
- _.mixin = function(obj) {
- _.each(_.functions(obj), function(name) {
- var func = _[name] = obj[name];
- _.prototype[name] = function() {
- var args = [this._wrapped];
- push.apply(args, arguments);
- return chainResult(this, func.apply(_, args));
- };
- });
- };
-
- // Add all of the Underscore functions to the wrapper object.
- _.mixin(_);
-
- // Add all mutator Array functions to the wrapper.
- _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
- var method = ArrayProto[name];
- _.prototype[name] = function() {
- var obj = this._wrapped;
- method.apply(obj, arguments);
- if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
- return chainResult(this, obj);
- };
- });
-
- // Add all accessor Array functions to the wrapper.
- _.each(['concat', 'join', 'slice'], function(name) {
- var method = ArrayProto[name];
- _.prototype[name] = function() {
- return chainResult(this, method.apply(this._wrapped, arguments));
- };
- });
-
- // Extracts the result from a wrapped and chained object.
- _.prototype.value = function() {
- return this._wrapped;
- };
-
- // Provide unwrapping proxy for some methods used in engine operations
- // such as arithmetic and JSON stringification.
- _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
-
- _.prototype.toString = function() {
- return '' + this._wrapped;
- };
-
- // AMD registration happens at the end for compatibility with AMD loaders
- // that may not enforce next-turn semantics on modules. Even though general
- // practice for AMD registration is to be anonymous, underscore registers
- // as a named module because, like jQuery, it is a base library that is
- // popular enough to be bundled in a third party lib, but not be part of
- // an AMD load request. Those cases could generate an error when an
- // anonymous define() is called outside of a loader request.
- if (typeof define == 'function' && define.amd) {
- define('underscore', [], function() {
- return _;
- });
- }
-}());