1 /* See license.txt for terms of usage */
  2 
  3 define([
  4     "firebug/lib/trace",
  5     "firebug/lib/locale",
  6 ],
  7 function(FBTrace, Locale) {
  8 
  9 // ********************************************************************************************* //
 10 // Constants
 11 
 12 var Cc = Components.classes;
 13 var Ci = Components.interfaces;
 14 var Cu = Components.utils;
 15 
 16 // ********************************************************************************************* //
 17 // Overlay Helpers
 18 
 19 var BrowserOverlayLib =
 20 {
 21     $: function(doc, id)
 22     {
 23         return doc.getElementById(id);
 24     },
 25 
 26     $$: function(doc, selector)
 27     {
 28         return doc.querySelectorAll(selector);
 29     },
 30 
 31     $el: function(doc, name, attributes, children, parent)
 32     {
 33         if (!(doc instanceof Ci.nsIDOMDocument))
 34         {
 35             if (FBTrace.DBG_ERRORS)
 36                 FBTrace.sysout("browserOvelayLib.$el; No document!")
 37             return;
 38         }
 39 
 40         attributes = attributes || {};
 41 
 42         if (!Array.isArray(children) && !parent)
 43         {
 44             parent = children;
 45             children = null;
 46         }
 47 
 48         // localize
 49         if (attributes.label)
 50             attributes.label = Locale.$STR(attributes.label);
 51 
 52         if (attributes.tooltiptext)
 53             attributes.tooltiptext = Locale.$STR(attributes.tooltiptext);
 54 
 55         // persist
 56         if (attributes.persist)
 57             updatePersistedValues(doc, attributes);
 58 
 59         var el = doc.createElement(name);
 60         for (var a in attributes)
 61             el.setAttribute(a, attributes[a]);
 62 
 63         for each (var a in children)
 64             el.appendChild(a);
 65 
 66         if (parent)
 67         {
 68             if (attributes.position)
 69                 parent.insertBefore(el, parent.children[attributes.position - 1]);
 70             else
 71                 parent.appendChild(el);
 72 
 73             // Mark to remove when Firebug is uninstalled.
 74             el.setAttribute("firebugRootNode", true);
 75         }
 76 
 77         return el;
 78     },
 79 
 80     $command: function(doc, id, oncommand, arg)
 81     {
 82         // Wrap the command within a startFirebug call. If Firebug isn't yet loaded
 83         // this will force it to load.
 84         oncommand = "Firebug.browserOverlay.startFirebug(function(){" + oncommand + "})";
 85         if (arg)
 86             oncommand = "void function(arg){" + oncommand + "}(" + arg + ")";
 87 
 88         return this.$el(doc, "command", {
 89             id: id,
 90             oncommand: oncommand
 91         }, this.$(doc, "mainCommandSet"))
 92     },
 93 
 94     $key: function(doc, id, key, modifiers, command, position)
 95     {
 96         var attributes = {
 97             id: id,
 98             modifiers: modifiers,
 99             command: command,
100             position: position
101         };
102 
103         attributes[KeyEvent["DOM_" + key] ? "keycode" : "key"] = key;
104 
105         return this.$el(doc, "key", attributes, $(doc, "mainKeyset"));
106     },
107 
108     $menupopup: function(doc, attributes, children, parent)
109     {
110         return this.$el(doc, "menupopup", attributes, children, parent);
111     },
112 
113     $menu: function(doc, attrs, children)
114     {
115         return this.$el(doc, "menu", attrs, children);
116     },
117 
118     $menuseparator: function(doc, attrs)
119     {
120         return this.$el(doc, "menuseparator", attrs);
121     },
122 
123     $menuitem: function(doc, attrs)
124     {
125         return this.$el(doc, "menuitem", attrs);
126     },
127 
128     $splitmenu: function(doc, attrs, children)
129     {
130         return this.$el(doc, "splitmenu", attrs, children);
131     },
132 
133     $menupopupOverlay: function(doc, parent, children)
134     {
135         if (!parent)
136             return;
137 
138         for (var i=0; i<children.length; ++i)
139         {
140             var child = children[i];
141             var beforeEl;
142 
143             if (child.getAttribute("position"))
144             {
145                 var pos = child.getAttribute("position");
146                 beforeEl = parent.children[pos - 1];
147             }
148             else if (child.getAttribute("insertbefore"))
149             {
150                 var ids = child.getAttribute("insertbefore").split(",");
151                 for (var j=0; j < ids.length; ++j)
152                 {
153                     beforeEl = parent.querySelector("#" + ids[j]);
154                     if (beforeEl)
155                         break;
156                 }
157             }
158             else if (child.getAttribute("insertafter"))
159             {
160                 var ids = child.getAttribute("insertafter").split(",");
161                 for (var j=0; j < ids.length; ++j)
162                 {
163                     beforeEl = parent.querySelector("#" + ids[j]);
164                     if (beforeEl)
165                         break;
166                 }
167                 if (beforeEl)
168                     beforeEl = beforeEl.nextSibling;
169             }
170 
171             if (beforeEl)
172                 parent.insertBefore(child, beforeEl);
173             else
174                 parent.appendChild(child);
175 
176             // Mark the inserted node to remove it when Firebug is uninstalled.
177             child.setAttribute("firebugRootNode", true);
178         }
179     },
180 
181     $toolbarButton: function(doc, id, attrs, children, defaultPos)
182     {
183         attrs["class"] = "toolbarbutton-1";
184         attrs.firebugRootNode = true;
185         attrs.id = id;
186 
187         // in seamonkey gNavToolbox is null onload
188         var button = this.$el(doc, "toolbarbutton", attrs, children,
189             (doc.defaultView.gNavToolbox || this.$(doc, "navigator-toolbox")).palette);
190 
191         var selector = "[currentset^='" + id + ",'],[currentset*='," + id +
192             ",'],[currentset$='," + id + "']";
193 
194         var toolbar = doc.querySelector(selector);
195         if (!toolbar)
196             return; // todo defaultPos
197 
198         var currentset = toolbar.getAttribute("currentset").split(",");
199         var i = currentset.indexOf(id) + 1;
200 
201         var len = currentset.length, beforeEl;
202         while (i < len && !(beforeEl = this.$(doc, currentset[i])))
203             i++;
204 
205         return toolbar.insertItem(id, beforeEl);
206     },
207 
208     $tooltip: function(doc, attrs, children)
209     {
210         return this.$el(doc, "tooltip", attrs, children);
211     },
212 
213     $label: function(doc, attrs)
214     {
215         return this.$el(doc, "label", attrs);
216     },
217 
218     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
219     // Stylesheets & Scripts
220 
221     $stylesheet: function(doc, href)
222     {
223         var s = doc.createProcessingInstruction("xml-stylesheet", 'href="' + href + '"');
224         doc.insertBefore(s, doc.documentElement);
225         return s;
226     },
227 
228     $script: function(doc, src)
229     {
230         var script = doc.createElementNS("http://www.w3.org/1999/xhtml", "html:script");
231         script.src = src;
232         script.type = "text/javascript";
233         script.setAttribute("firebugRootNode", true);
234         doc.documentElement.appendChild(script);
235     },
236 }
237 
238 // ********************************************************************************************* //
239 // Helpers
240 
241 function updatePersistedValues(doc, options)
242 {
243     var persist = options.persist.split(",");
244     var id = options.id;
245     var RDF = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
246     var store = doc.defaultView.PlacesUIUtils.localStore; //this.RDF.GetDataSource("rdf:local-store");
247     var root = RDF.GetResource("chrome://browser/content/browser.xul#" + id);
248 
249     var getPersist = function getPersist(aProperty)
250     {
251         var property = RDF.GetResource(aProperty);
252         var target = store.GetTarget(root, property, true);
253 
254         if (target instanceof Ci.nsIRDFLiteral)
255             return target.Value;
256     }
257 
258     for each(var attr in persist)
259     {
260         var val = getPersist(attr);
261         if (val)
262             options[attr] = val;
263     }
264 }
265 
266 // ********************************************************************************************* //
267 // Registration
268 
269 return BrowserOverlayLib;
270 
271 // ********************************************************************************************* //
272 });
273