function Discovery() { EventEmitter.decorate(this); this.localServices = {}; this.remoteServices = {}; this.device = { name: "unknown" }; this.replyTimeout = REPLY_TIMEOUT; // Defaulted to Transport, but can be altered by tests this._factories = { Transport: Transport }; this._transports = { scan: null, update: null }; this._expectingReplies = { from: new Set() }; this._onRemoteScan = this._onRemoteScan.bind(this); this._onRemoteUpdate = this._onRemoteUpdate.bind(this); this._purgeMissingDevices = this._purgeMissingDevices.bind(this); this._getSystemInfo(); }
function WebAudioEditorPanel (iframeWindow, toolbox) { this.panelWin = iframeWindow; this._toolbox = toolbox; this._destroyer = null; EventEmitter.decorate(this); }
function CanvasDebuggerPanel(iframeWindow, toolbox) { this.panelWin = iframeWindow; this._toolbox = toolbox; this._destroyer = null; EventEmitter.decorate(this); };
/** * ToolSidebar provides methods to register tabs in the sidebar. * It's assumed that the sidebar contains a xul:tabbox. * * @param {Node} tabbox * <tabbox> node; * @param {ToolPanel} panel * Related ToolPanel instance; * @param {String} uid * Unique ID * @param {Boolean} showTabstripe * Show the tabs. */ function ToolSidebar(tabbox, panel, uid, showTabstripe=true) { EventEmitter.decorate(this); this._tabbox = tabbox; this._uid = uid; this._panelDoc = this._tabbox.ownerDocument; this._toolPanel = panel; try { this._width = Services.prefs.getIntPref("devtools.toolsidebar-width." + this._uid); } catch(e) {} this._telemetry = new Telemetry(); this._tabbox.tabpanels.addEventListener("select", this, true); this._tabs = new Map(); if (!showTabstripe) { this._tabbox.setAttribute("hidetabs", "true"); } this._toolPanel.emit("sidebar-created", this); }
function mergeStores(stores) { let finalStore = {object:{}}; EventEmitter.decorate(finalStore); let setEventForwarders = {}; for (let key in stores) { let store = stores[key]; finalStore.object[key] = store.object; setEventForwarders[key] = _createSetEventForwarder(key, finalStore); store.on("set", setEventForwarders[key]); } finalStore.destroy = () => { for (let key in stores) { let store = stores[key]; store.off("set", setEventForwarders[key]); if (store.destroy) { store.destroy(); } } }; return finalStore; }
function Discovery() { EventEmitter.decorate(this); this.localServices = {}; this.remoteServices = {}; this.device = new LocalDevice(); this.replyTimeout = REPLY_TIMEOUT; // Defaulted to Transport, but can be altered by tests this._factories = { Transport: Transport }; this._transports = { scan: null, update: null }; this._expectingReplies = { from: new Set() }; this._onRemoteScan = this._onRemoteScan.bind(this); this._onRemoteUpdate = this._onRemoteUpdate.bind(this); this._purgeMissingDevices = this._purgeMissingDevices.bind(this); Services.obs.addObserver(this, "network-active-changed", false); }
const FastListWidget = module.exports = function FastListWidget(aNode) { this.document = aNode.ownerDocument; this.window = this.document.defaultView; this._parent = aNode; this._fragment = this.document.createDocumentFragment(); // This is a prototype element that each item added to the list clones. this._templateElement = this.document.createElement("hbox"); // Create an internal scrollbox container. this._list = this.document.createElement("scrollbox"); this._list.className = "fast-list-widget-container theme-body"; this._list.setAttribute("flex", "1"); this._list.setAttribute("orient", "vertical"); this._list.setAttribute("tabindex", "0"); this._list.addEventListener("keypress", e => this.emit("keyPress", e), false); this._list.addEventListener("mousedown", e => this.emit("mousePress", e), false); this._parent.appendChild(this._list); this._orderedMenuElementsArray = []; this._itemsByElement = new Map(); // This widget emits events that can be handled in a MenuContainer. EventEmitter.decorate(this); // Delegate some of the associated node's methods to satisfy the interface // required by MenuContainer instances. ViewHelpers.delegateWidgetAttributeMethods(this, aNode); ViewHelpers.delegateWidgetEventMethods(this, aNode); }
function ADBAddon() { EventEmitter.decorate(this); // This addon uses the string "linux" for "linux32" let fixedOS = OS == "linux32" ? "linux" : OS; this.xpiLink = ADB_LINK.replace(/#OS#/g, fixedOS); this.addonID = ADB_ADDON_ID; this.updateInstallStatus(); }
/** * A MonitorClient is used as an actor client of a runtime's monitor actors, * receiving its updates. */ function MonitorClient(client, form) { this.client = client; this.actor = form.monitorActor; this.events = ['update']; EventEmitter.decorate(this); this.client.registerClient(this); }
/** * API * * new Selection(walker=null, node=null, track={attributes,detached}); * destroy() * node (readonly) * setNode(node, origin="unknown") * * Helpers: * * window * document * isRoot() * isNode() * isHTMLNode() * * Check the nature of the node: * * isElementNode() * isAttributeNode() * isTextNode() * isCDATANode() * isEntityRefNode() * isEntityNode() * isProcessingInstructionNode() * isCommentNode() * isDocumentNode() * isDocumentTypeNode() * isDocumentFragmentNode() * isNotationNode() * * Events: * "new-node" when the inner node changed * "before-new-node" when the inner node is set to change * "attribute-changed" when an attribute is changed (only if tracked) * "detached" when the node (or one of its parents) is removed from the document (only if tracked) * "reparented" when the node (or one of its parents) is moved under a different node (only if tracked) */ /** * A Selection object. Hold a reference to a node. * Includes some helpers, fire some helpful events. * * @param node Inner node. * Can be null. Can be (un)set in the future via the "node" property; * @param trackAttribute Tell if events should be fired when the attributes of * the node change. * */ function Selection(walker, node=null, track={attributes:true,detached:true}) { EventEmitter.decorate(this); this._onMutations = this._onMutations.bind(this); this.track = track; this.setWalker(walker); this.setNode(node); }
this.StoragePanel = function StoragePanel(panelWin, toolbox) { EventEmitter.decorate(this); this._toolbox = toolbox; this._target = toolbox.target; this._panelWin = panelWin; this.destroy = this.destroy.bind(this); }
/** * Represents the Options Panel in the Toolbox. */ function OptionsPanel(iframeWindow, toolbox) { this.panelDoc = iframeWindow.document; this.panelWin = iframeWindow; this.toolbox = toolbox; this.isReady = false; const EventEmitter = require("devtools/toolkit/event-emitter"); EventEmitter.decorate(this); }
/** * Each Transport instance owns a single UDPSocket. * @param port integer * The port to listen on for incoming UDP multicast packets. */ function Transport(port) { EventEmitter.decorate(this); try { this.socket = new UDPSocket(port, false); this.socket.joinMulticast(ADDRESS); this.socket.asyncListen(this); } catch(e) { log("Failed to start new socket: " + e); } }
/** * `AppActorFront` is a client for the webapps actor. */ function AppActorFront(client, form) { this.client = client; this.actor = form.webappsActor; this._clientListener = this._clientListener.bind(this); this._onInstallProgress = this._onInstallProgress.bind(this); this._listeners = []; EventEmitter.decorate(this); }
this.StyleEditorPanel = function StyleEditorPanel(panelWin, toolbox) { EventEmitter.decorate(this); this._toolbox = toolbox; this._target = toolbox.target; this._panelWin = panelWin; this._panelDoc = panelWin.document; this.destroy = this.destroy.bind(this); this._showError = this._showError.bind(this); }
/** * Spectrum creates a color picker widget in any container you give it. * * Simple usage example: * * const {Spectrum} = require("devtools/shared/widgets/Spectrum"); * let s = new Spectrum(containerElement, [255, 126, 255, 1]); * s.on("changed", (event, rgba, color) => { * console.log("rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ", " + rgba[3] + ")"); * }); * s.show(); * s.destroy(); * * Note that the color picker is hidden by default and you need to call show to * make it appear. This 2 stages initialization helps in cases you are creating * the color picker in a parent element that hasn't been appended anywhere yet * or that is hidden. Calling show() when the parent element is appended and * visible will allow spectrum to correctly initialize its various parts. * * Fires the following events: * - changed : When the user changes the current color */ function Spectrum(parentEl, rgb) { EventEmitter.decorate(this); this.element = parentEl.ownerDocument.createElement('div'); this.parentEl = parentEl; this.element.className = "spectrum-container"; this.element.innerHTML = [ "<div class='spectrum-top'>", "<div class='spectrum-fill'></div>", "<div class='spectrum-top-inner'>", "<div class='spectrum-color spectrum-box'>", "<div class='spectrum-sat'>", "<div class='spectrum-val'>", "<div class='spectrum-dragger'></div>", "</div>", "</div>", "</div>", "<div class='spectrum-hue spectrum-box'>", "<div class='spectrum-slider spectrum-slider-control'></div>", "</div>", "</div>", "</div>", "<div class='spectrum-alpha spectrum-checker spectrum-box'>", "<div class='spectrum-alpha-inner'>", "<div class='spectrum-alpha-handle spectrum-slider-control'></div>", "</div>", "</div>", ].join(""); this.onElementClick = this.onElementClick.bind(this); this.element.addEventListener("click", this.onElementClick, false); this.parentEl.appendChild(this.element); this.slider = this.element.querySelector(".spectrum-hue"); this.slideHelper = this.element.querySelector(".spectrum-slider"); Spectrum.draggable(this.slider, this.onSliderMove.bind(this)); this.dragger = this.element.querySelector(".spectrum-color"); this.dragHelper = this.element.querySelector(".spectrum-dragger"); Spectrum.draggable(this.dragger, this.onDraggerMove.bind(this)); this.alphaSlider = this.element.querySelector(".spectrum-alpha"); this.alphaSliderInner = this.element.querySelector(".spectrum-alpha-inner"); this.alphaSliderHelper = this.element.querySelector(".spectrum-alpha-handle"); Spectrum.draggable(this.alphaSliderInner, this.onAlphaSliderMove.bind(this)); if (rgb) { this.rgb = rgb; this.updateUI(); } }
function SimulatorAddon(stability, version) { EventEmitter.decorate(this); this.stability = stability; this.version = version; // This addon uses the string "linux" for "linux32" let fixedOS = OS == "linux32" ? "linux" : OS; this.xpiLink = SIMULATOR_LINK.replace(/#OS#/g, fixedOS) .replace(/#VERSION#/g, version) .replace(/#SLASHED_VERSION#/g, version.replace(/\./g, "_")); this.addonID = SIMULATOR_ADDON_ID.replace(/#SLASHED_VERSION#/g, version.replace(/\./g, "_")); this.updateInstallStatus(); }
/** * Represents an open instance of the Inspector for a tab. * The inspector controls the breadcrumbs, the markup view, and the sidebar * (computed view, rule view, font view and layout view). * * Events: * - ready * Fired when the inspector panel is opened for the first time and ready to * use * - new-root * Fired after a new root (navigation to a new page) event was fired by * the walker, and taken into account by the inspector (after the markup * view has been reloaded) * - markuploaded * Fired when the markup-view frame has loaded * - layout-change * Fired when the layout of the inspector changes * - breadcrumbs-updated * Fired when the breadcrumb widget updates to a new node * - layoutview-updated * Fired when the layoutview (box model) updates to a new node * - markupmutation * Fired after markup mutations have been processed by the markup-view * - computed-view-refreshed * Fired when the computed rules view updates to a new node * - computed-view-property-expanded * Fired when a property is expanded in the computed rules view * - computed-view-property-collapsed * Fired when a property is collapsed in the computed rules view * - computed-view-sourcelinks-updated * Fired when the stylesheet source links have been updated (when switching * to source-mapped files) * - rule-view-refreshed * Fired when the rule view updates to a new node * - rule-view-sourcelinks-updated * Fired when the stylesheet source links have been updated (when switching * to source-mapped files) */ function InspectorPanel(iframeWindow, toolbox) { this._toolbox = toolbox; this._target = toolbox._target; this.panelDoc = iframeWindow.document; this.panelWin = iframeWindow; this.panelWin.inspector = this; this._onBeforeNavigate = this._onBeforeNavigate.bind(this); this._target.on("will-navigate", this._onBeforeNavigate); EventEmitter.decorate(this); }
/** * Represents the Options Panel in the Toolbox. */ function OptionsPanel(iframeWindow, toolbox) { this.panelDoc = iframeWindow.document; this.panelWin = iframeWindow; this.toolbox = toolbox; this.isReady = false; this._prefChanged = this._prefChanged.bind(this); this._addListeners(); const EventEmitter = require("devtools/toolkit/event-emitter"); EventEmitter.decorate(this); }
/** * The LayoutChangesObserver class is instantiated only once per given tab * and is used to track reflows and dom and style changes in that tab. * The LayoutActor uses this class to send reflow events to its clients. * * This class isn't exported on the module because it shouldn't be instantiated * to avoid creating several instances per tabs. * Use `getLayoutChangesObserver(tabActor)` * and `releaseLayoutChangesObserver(tabActor)` * which are exported to get and release instances. * * The observer loops every EVENT_BATCHING_DELAY ms and checks if layout changes * have happened since the last loop iteration. If there are, it sends the * corresponding events: * * - "reflows", with an array of all the reflows that occured, * * @param {TabActor} tabActor */ function LayoutChangesObserver(tabActor) { Observable.call(this, tabActor); this._startEventLoop = this._startEventLoop.bind(this); // Creating the various observers we're going to need // For now, just the reflow observer, but later we can add markupMutation, // styleSheetChanges and styleRuleChanges this._onReflow = this._onReflow.bind(this); this.reflowObserver = new ReflowObserver(this.tabActor, this._onReflow); EventEmitter.decorate(this); }
/** * Tooltip class. * * Basic usage: * let t = new Tooltip(xulDoc); * t.content = someXulContent; * t.show(); * t.hide(); * t.destroy(); * * Better usage: * let t = new Tooltip(xulDoc); * t.startTogglingOnHover(container, target => { * if (<condition based on target>) { * t.setImageContent("http://image.png"); * return true; * } * }); * t.destroy(); * * @param {XULDocument} doc * The XUL document hosting this tooltip * @param {Object} options * Optional options that give options to consumers: * - consumeOutsideClick {Boolean} Wether the first click outside of the * tooltip should close the tooltip and be consumed or not. * Defaults to false. * - closeOnKeys {Array} An array of key codes that should close the * tooltip. Defaults to [27] (escape key). * - closeOnEvents [{emitter: {Object}, event: {String}, useCapture: {Boolean}}] * Provide an optional list of emitter objects and event names here to * trigger the closing of the tooltip when these events are fired by the * emitters. The emitter objects should either implement on/off(event, cb) * or addEventListener/removeEventListener(event, cb). Defaults to []. * For instance, the following would close the tooltip whenever the * toolbox selects a new tool and when a DOM node gets scrolled: * new Tooltip(doc, { * closeOnEvents: [ * {emitter: toolbox, event: "select"}, * {emitter: myContainer, event: "scroll", useCapture: true} * ] * }); * - noAutoFocus {Boolean} Should the focus automatically go to the panel * when it opens. Defaults to true. * * Fires these events: * - showing : just before the tooltip shows * - shown : when the tooltip is shown * - hiding : just before the tooltip closes * - hidden : when the tooltip gets hidden * - keypress : when any key gets pressed, with keyCode */ function Tooltip(doc, options) { EventEmitter.decorate(this); this.doc = doc; this.options = new OptionsStore({ consumeOutsideClick: false, closeOnKeys: [ESCAPE_KEYCODE], noAutoFocus: true, closeOnEvents: [] }, options); this.panel = PanelFactory.get(doc, this.options); // Used for namedTimeouts in the mouseover handling this.uid = "tooltip-" + Date.now(); // Emit show/hide events for (let event of POPUP_EVENTS) { this["_onPopup" + event] = ((e) => { return () => this.emit(e); })(event); this.panel.addEventListener("popup" + event, this["_onPopup" + event], false); } // Listen to keypress events to close the tooltip if configured to do so let win = this.doc.querySelector("window"); this._onKeyPress = event => { if (this.panel.hidden) { return; } this.emit("keypress", event.keyCode); if (this.options.get("closeOnKeys").indexOf(event.keyCode) !== -1) { event.stopPropagation(); this.hide(); } }; win.addEventListener("keypress", this._onKeyPress, false); // Listen to custom emitters' events to close the tooltip this.hide = this.hide.bind(this); let closeOnEvents = this.options.get("closeOnEvents"); for (let {emitter, event, useCapture} of closeOnEvents) { for (let add of ["addEventListener", "on"]) { if (add in emitter) { emitter[add](event, this.hide, useCapture); break; } } } }
const OptionsView = function (options={}) { this.branchName = options.branchName; this.menupopup = options.menupopup; this.window = this.menupopup.ownerDocument.defaultView; let { document } = this.window; this.$ = document.querySelector.bind(document); this.$$ = (selector, parent=document) => parent.querySelectorAll(selector); // Get the corresponding button that opens the popup by looking // for an element with a `popup` attribute matching the menu's ID this.button = this.$(`[popup=${this.menupopup.getAttribute("id")}]`); this.prefObserver = new PrefObserver(this.branchName); EventEmitter.decorate(this); };
module.exports = ProjectList = function(window, parentWindow) { EventEmitter.decorate(this); this._doc = window.document; this._UI = parentWindow.UI; this._parentWindow = parentWindow; this._panelNodeEl = "toolbarbutton"; this._sidebarsEnabled = Services.prefs.getBoolPref("devtools.webide.sidebars"); if (this._sidebarsEnabled) { this._panelNodeEl = "div"; } AppManager.init(); return this; };
/** * A TabTarget represents a page living in a browser tab. Generally these will * be web pages served over http(s), but they don't have to be. */ function TabTarget(tab) { EventEmitter.decorate(this); this.destroy = this.destroy.bind(this); this._handleThreadState = this._handleThreadState.bind(this); this.on("thread-resumed", this._handleThreadState); this.on("thread-paused", this._handleThreadState); // Only real tabs need initialization here. Placeholder objects for remote // targets will be initialized after a makeRemote method call. if (tab && !["client", "form", "chrome"].every(tab.hasOwnProperty, tab)) { this._tab = tab; this._setupListeners(); } else { this._form = tab.form; this._client = tab.client; this._chrome = tab.chrome; } }
/** * CubicBezierPreset widget. * Builds a menu of presets from CubicBezierPresets * @param {DOMNode} parent The container where the preset panel should be created * * Emits "new-coordinate" event along with the coordinates * whenever a preset is selected. */ function CubicBezierPresetWidget(parent) { this.parent = parent; let {presetPane, presets, categories} = this._initMarkup(); this.presetPane = presetPane; this.presets = presets; this.categories = categories; this._activeCategory = null; this._activePresetList = null; this._activePreset = null; this._onCategoryClick = this._onCategoryClick.bind(this); this._onPresetClick = this._onPresetClick.bind(this); EventEmitter.decorate(this); this._initEvents(); }
/** * A TabTarget represents a page living in a browser tab. Generally these will * be web pages served over http(s), but they don't have to be. */ function TabTarget(tab) { EventEmitter.decorate(this); this.destroy = this.destroy.bind(this); this._handleThreadState = this._handleThreadState.bind(this); this.on("thread-resumed", this._handleThreadState); this.on("thread-paused", this._handleThreadState); // Only real tabs need initialization here. Placeholder objects for remote // targets will be initialized after a makeRemote method call. if (tab && !["client", "form", "chrome"].every(tab.hasOwnProperty, tab)) { this._tab = tab; this._setupListeners(); } else { this._form = tab.form; this._client = tab.client; this._chrome = tab.chrome; } // Default isTabActor to true if not explicitely specified this._isTabActor = typeof(tab.isTabActor) == "boolean" ? tab.isTabActor : true; }
/** * Represents the Options Panel in the Toolbox. */ function OptionsPanel(iframeWindow, toolbox) { this.panelDoc = iframeWindow.document; this.panelWin = iframeWindow; this.toolbox = toolbox; this.isReady = false; this._prefChanged = this._prefChanged.bind(this); this._themeRegistered = this._themeRegistered.bind(this); this._themeUnregistered = this._themeUnregistered.bind(this); this._disableJSClicked = this._disableJSClicked.bind(this); this.disableJSNode = this.panelDoc.getElementById("devtools-disable-javascript"); this._addListeners(); const EventEmitter = require("devtools/toolkit/event-emitter"); EventEmitter.decorate(this); }
/** * Manages all highlighters in the style-inspector. * @param {CssRuleView|CssComputedView} view Either the rule-view or computed-view * panel */ function HighlightersOverlay(view) { this.view = view; let {CssRuleView} = require("devtools/styleinspector/rule-view"); this.isRuleView = view instanceof CssRuleView; this.highlighterUtils = this.view.inspector.toolbox.highlighterUtils; this._onMouseMove = this._onMouseMove.bind(this); this._onMouseLeave = this._onMouseLeave.bind(this); this.promises = {}; this.highlighters = {}; // Only initialize the overlay if at least one of the highlighter types is // supported this.supportsHighlighters = this.highlighterUtils.supportsCustomHighlighters(); EventEmitter.decorate(this); }
/** * A "Toolbox" is the component that holds all the tools for one specific * target. Visually, it's a document that includes the tools tabs and all * the iframes where the tool panels will be living in. * * @param {object} target * The object the toolbox is debugging. * @param {string} selectedTool * Tool to select initially * @param {Toolbox.HostType} hostType * Type of host that will host the toolbox (e.g. sidebar, window) * @param {object} hostOptions * Options for host specifically */ function Toolbox(target, selectedTool, hostType, hostOptions) { this._target = target; this._toolPanels = new Map(); this._telemetry = new Telemetry(); this._toolRegistered = this._toolRegistered.bind(this); this._toolUnregistered = this._toolUnregistered.bind(this); this._refreshHostTitle = this._refreshHostTitle.bind(this); this._splitConsoleOnKeypress = this._splitConsoleOnKeypress.bind(this); this.destroy = this.destroy.bind(this); this.highlighterUtils = getHighlighterUtils(this); this._highlighterReady = this._highlighterReady.bind(this); this._highlighterHidden = this._highlighterHidden.bind(this); this._prefChanged = this._prefChanged.bind(this); this._saveSplitConsoleHeight = this._saveSplitConsoleHeight.bind(this); this._onFocus = this._onFocus.bind(this); this._target.on("close", this.destroy); if (!hostType) { hostType = Services.prefs.getCharPref(this._prefs.LAST_HOST); } if (!selectedTool) { selectedTool = Services.prefs.getCharPref(this._prefs.LAST_TOOL); } if (!gDevTools.getToolDefinition(selectedTool)) { selectedTool = "webconsole"; } this._defaultToolId = selectedTool; this._host = this._createHost(hostType, hostOptions); EventEmitter.decorate(this); this._target.on("navigate", this._refreshHostTitle); this.on("host-changed", this._refreshHostTitle); this.on("select", this._refreshHostTitle); gDevTools.on("tool-registered", this._toolRegistered); gDevTools.on("tool-unregistered", this._toolUnregistered); }
let StorageUI = this.StorageUI = function StorageUI(front, target, panelWin) { EventEmitter.decorate(this); this._target = target; this._window = panelWin; this._panelDoc = panelWin.document; this.front = front; let treeNode = this._panelDoc.getElementById("storage-tree"); this.tree = new TreeWidget(treeNode, {defaultType: "dir"}); this.onHostSelect = this.onHostSelect.bind(this); this.tree.on("select", this.onHostSelect); let tableNode = this._panelDoc.getElementById("storage-table"); this.table = new TableWidget(tableNode, { emptyText: L10N.getStr("table.emptyText"), highlightUpdated: true, }); this.displayObjectSidebar = this.displayObjectSidebar.bind(this); this.table.on(TableWidget.EVENTS.ROW_SELECTED, this.displayObjectSidebar); this.sidebar = this._panelDoc.getElementById("storage-sidebar"); this.sidebar.setAttribute("width", "300"); this.view = new VariablesView(this.sidebar.firstChild, GENERIC_VARIABLES_VIEW_SETTINGS); this.front.listStores().then(storageTypes => { this.populateStorageTree(storageTypes); }).then(null, console.error); this.onUpdate = this.onUpdate.bind(this); this.front.on("stores-update", this.onUpdate); this.onCleared = this.onCleared.bind(this); this.front.on("stores-cleared", this.onCleared); this.handleKeypress = this.handleKeypress.bind(this); this._panelDoc.addEventListener("keypress", this.handleKeypress); this._telemetry = new Telemetry(); this._telemetry.toolOpened("storage"); };