diff --git a/PanelSplitter/bootstrap.js b/PanelSplitter/bootstrap.js new file mode 100644 index 0000000..9c3f413 --- /dev/null +++ b/PanelSplitter/bootstrap.js @@ -0,0 +1,152 @@ +/* See license.txt for terms of usage */ + +// ********************************************************************************************* // +// XPCOM + +var {classes: Cc, interfaces: Ci, utils: Cu} = Components; + +// ********************************************************************************************* // +// Constants + +// Extension installation path. Set within startup callback. +var installPath; + +// ********************************************************************************************* // +// Firefox Bootstrap API + +function install(data, reason) {} +function uninstall(data, reason) {} + +function startup(data, reason) +{ + // Remember so, we can use later within firebugStartup callback. + installPath = data.installPath; + + // Firebug extension start-up callback. Since extension load order isn't guaranteed + // the code needs to be ready for two alternatives: + // 1) Firebug is already loaded - good, let's just execute firebugStartup() callback + // that will ensure proper Firebug related initialization for this extension. + // 2) Firebug is not loaded yet - as soon as Firebug is loaded it'll execute this + // method automatically. + firebugStartup(); +} + +function shutdown(data, reason) +{ + firebugShutdown(); +} + +function isFirebugLoaded() +{ + try + { + // Import Firebug modules into this scope. It fails if Firebug isn't loaded yet. + Cu.import("resource://firebug/loader.js"); + Cu.import("resource://firebug/prefLoader.js"); + + return true; + } + catch (e) + { + // Report the error only if you want to track cases where this extension + // is loaded before Firebug. + //Cu.reportError(e); + } + + return false; +} + +// ********************************************************************************************* // +// Firebug Bootstrap API + +/** + * Executed by Firebug framework when Firebug is started. Since the order of Firebug + * and its bootstrapped extensions is not guaranteed this function is executed twice. + * 1) When Firebug is loaded + * 2) When this extension is loaded + */ +function firebugStartup() +{ + // If Firebug isn't loaded just bail out, Firebug will execute this method + // as soon as it loads. + if (!isFirebugLoaded()) + return; + + // At this point, Firebug is loaded and we can use its API. + FirebugLoader.registerBootstrapScope(this); + + // Load default preferences + PrefLoader.loadDefaultPrefs(installPath, "prefs.js"); +} + +/** + * Executed by Firefox when this extension shutdowns. + */ +function firebugShutdown() +{ + try + { + FirebugLoader.unregisterBootstrapScope(this); + } + catch (e) + { + Cu.reportError(e); + } +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +/** + * Executed by Firebug framework for every browser window. Use this function to append + * any new elements into the browser window (browser.xul). Don't forget to remove + * these elements in topWindowUnload. + * + * @param {Window} win The browser window + */ +function topWindowLoad(win) +{ + // TODO: overlay global browser window +} + +/** + * Executed by Firebug framework when this extension + * @param {Object} win + */ +function topWindowUnload(win) +{ + // TODO: remove global browser window overlays +} + +/** + * Entire Firebug UI is running inside an iframe (firebugFrame.xul). This function + * is executed by Firebug framework when the frame is loaded. This happens when + * the user requires Firebug for the first time (doesn't have to happen during the + * Firefox session at all) + * + * @param {Window} win The Firebug window + */ +function firebugFrameLoad(Firebug) +{ + // Register trace listener the customizes trace logs coming from this extension + // * panelSplitter; is unique prefix of all messages that should be customized. + // * DBG_PANELSPLITTER is a class name with style defined in the specified stylesheet. + Firebug.registerTracePrefix("panelSplitter;", "DBG_PANELSPLITTER", true, + "chrome://panelsplitter/skin/panelsplitter.css"); + + // The registration process will automatically look for 'main' module and load it. + // The is the same what happens in a XUL overlay applied on: + // chrome://firebug/content/firebugOverlay.xul + var config = {id: "panelsplitter@janodvarko.cz"}; + Firebug.registerExtension("panelsplitter", config); +} + +function firebugFrameUnload(Firebug) +{ + if (!Firebug.isInitialized) + return; + + Firebug.unregisterExtension("panelsplitter"); + Firebug.unregisterTracePrefix("panelSplitter;"); +} + +// ********************************************************************************************* // diff --git a/PanelSplitter/chrome.manifest b/PanelSplitter/chrome.manifest new file mode 100644 index 0000000..804e10f --- /dev/null +++ b/PanelSplitter/chrome.manifest @@ -0,0 +1,3 @@ +content panelsplitter chrome/content/ +skin panelsplitter classic/1.0 chrome/skin/classic/ +locale panelsplitter en-US chrome/locale/en-US/ diff --git a/PanelSplitter/chrome/content/main.js b/PanelSplitter/chrome/content/main.js new file mode 100644 index 0000000..479adce --- /dev/null +++ b/PanelSplitter/chrome/content/main.js @@ -0,0 +1,41 @@ +/* See license.txt for terms of usage */ + +define([ + "firebug/lib/trace", + "panelsplitter/myPanel", +], +function(FBTrace, MyPanel) { + +// ********************************************************************************************* // +// The Application Object + +var theApp = +{ + initialize: function() + { + if (FBTrace.DBG_PANELSPLITTER) + FBTrace.sysout("panelSplitter; initialize"); + + // TODO: Extension initialization + }, + + shutdown: function() + { + if (FBTrace.DBG_PANELSPLITTER) + FBTrace.sysout("panelSplitter; shutdown"); + + // Unregister all registered Firebug components + Firebug.unregisterPanel(MyPanel); + Firebug.unregisterStylesheet("chrome://panelsplitter/skin/panelsplitter.css"); + Firebug.unregisterStringBundle("chrome://panelsplitter/locale/panelsplitter.properties"); + + // TODO: Extension shutdown + } +} + +// ********************************************************************************************* // + +return theApp; + +// ********************************************************************************************* // +}); diff --git a/PanelSplitter/chrome/content/myPanel.js b/PanelSplitter/chrome/content/myPanel.js new file mode 100644 index 0000000..de407e8 --- /dev/null +++ b/PanelSplitter/chrome/content/myPanel.js @@ -0,0 +1,116 @@ +/* See license.txt for terms of usage */ + +define([ + "firebug/lib/object", + "firebug/lib/trace", + "firebug/lib/locale", + "firebug/lib/domplate", + "firebug/lib/dom", + "firebug/lib/http", + "firebug/lib/wrapper", + "firebug/lib/array", + "firebug/lib/dragdrop", +], +function(Obj, FBTrace, Locale, Domplate, Dom, Http, Wrapper, Arr, DragDrop) { + +"use strict"; + +// ********************************************************************************************* // +// Custom Panel Implementation + +function MyPanel() {}; +MyPanel.prototype = Obj.extend(Firebug.Panel, +{ + name: "panelsplitter", + title: "Panel with a splitter", + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + // Initialization + + initialize: function() + { + Firebug.Panel.initialize.apply(this, arguments); + this.refresh(); + }, + + destroy: function(state) + { + Firebug.Panel.destroy.apply(this, arguments); + }, + + refresh: function() + { + this.MyTemplate.render(this.panelNode); + + // Initialize panel splitter + var handler = this.panelNode.querySelector(".myResizer"); + this.resizer = new DragDrop.Tracker(handler, { + onDragStart: Obj.bind(this.onDragStart, this), + onDragOver: Obj.bind(this.onDragOver, this), + onDrop: Obj.bind(this.onDrop, this) + }); + }, + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + // Splitter + + onDragStart: function(tracker) + { + var body = Dom.getBody(this.document); + body.setAttribute("resizingHtmlPreview", "true"); + + var topPane = this.panelNode.querySelector(".topPane"); + this.startHeight = topPane.clientHeight; + }, + + onDragOver: function(newPos, tracker) + { + var newHeight = (this.startHeight + newPos.y); + var topPane = this.panelNode.querySelector(".topPane"); + topPane.style.height = newHeight + "px"; + }, + + onDrop: function(tracker) + { + var body = Dom.getBody(this.document); + body.removeAttribute("resizingHtmlPreview"); + }, +}); + +// ********************************************************************************************* // +// Panel UI (Domplate) + +// Register strings before the following template definition. +Firebug.registerStringBundle("chrome://panelsplitter/locale/panelsplitter.properties"); + +var {domplate, DIV} = Domplate; + +MyPanel.prototype.MyTemplate = domplate( +{ + tag: + DIV( + DIV({"class": "topPane"}, + Locale.$STR("panelsplitter.panel.label1") + ), + DIV({"class": "myResizer"}), + DIV({"class": "bottomPane"}, + Locale.$STR("panelsplitter.panel.label2") + ) + ), + + render: function(parentNode) + { + this.tag.replace({}, parentNode); + } +}) + +// ********************************************************************************************* // +// Registration + +Firebug.registerPanel(MyPanel); +Firebug.registerStylesheet("chrome://panelsplitter/skin/panelsplitter.css"); + +return MyPanel; + +// ********************************************************************************************* // +}); diff --git a/PanelSplitter/chrome/locale/en-US/panelsplitter.properties b/PanelSplitter/chrome/locale/en-US/panelsplitter.properties new file mode 100644 index 0000000..8cf2cad --- /dev/null +++ b/PanelSplitter/chrome/locale/en-US/panelsplitter.properties @@ -0,0 +1,2 @@ +panelsplitter.panel.label1=Top panel. Min and max height of this panel is defined in panelsplitter.css +panelsplitter.panel.label2=Bottom panel diff --git a/PanelSplitter/chrome/skin/classic/panelsplitter.css b/PanelSplitter/chrome/skin/classic/panelsplitter.css new file mode 100644 index 0000000..25feb4a --- /dev/null +++ b/PanelSplitter/chrome/skin/classic/panelsplitter.css @@ -0,0 +1,36 @@ +/* See license.txt for terms of usage */ + +/*************************************************************************************************/ + +/* Style applied on the panel node. Rule syntax: .panelNode- */ +.panelNode-panelsplitter { + overflow: hidden; + padding: 0; + font-size: 12px; +} + +/*************************************************************************************************/ +/* Splitter */ + +.topPane { + height: 100px; + min-height: 25px; + max-height: 200px; +} + +.myResizer { + width: 100%; + height: 5px; + background-color: lightgrey; + cursor: s-resize; +} + +/*************************************************************************************************/ + +/* Firebug Tracing Console customization. All messages from this example use this color. + This helps to distinguish logs from those coming from Firebug + Rule syntax: .DBG_ + See: http://getfirebug.com/wiki/index.php/FBTrace for more details */ +.DBG_PANELSPLITTER { + color: rgb(101, 0, 114); +} diff --git a/PanelSplitter/defaults/preferences/prefs.js b/PanelSplitter/defaults/preferences/prefs.js new file mode 100644 index 0000000..1387bbb --- /dev/null +++ b/PanelSplitter/defaults/preferences/prefs.js @@ -0,0 +1 @@ +pref("extensions.firebug.DBG_PANELSPLITTER", true); diff --git a/PanelSplitter/install.rdf b/PanelSplitter/install.rdf new file mode 100644 index 0000000..5ecbe25 --- /dev/null +++ b/PanelSplitter/install.rdf @@ -0,0 +1,26 @@ + + + + panelsplitter@janodvarko.cz + 0.5 + 2 + true + + + + + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} + 10.0 + 30.* + + + + + PanelSplitter + Firebug extension example. + Jan Odvarko + http://getfirebug.com + + diff --git a/PanelSplitter/license.txt b/PanelSplitter/license.txt new file mode 100644 index 0000000..985d5fc --- /dev/null +++ b/PanelSplitter/license.txt @@ -0,0 +1,30 @@ +Software License Agreement (BSD License) + +Copyright (c) 2009, Mozilla Foundation +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 Mozilla Foundation nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Mozilla Foundation + +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.