browser/base/content/socialmarks.xml

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 <?xml version="1.0"?>
michael@0 2
michael@0 3 <bindings id="socialMarkBindings"
michael@0 4 xmlns="http://www.mozilla.org/xbl"
michael@0 5 xmlns:xbl="http://www.mozilla.org/xbl"
michael@0 6 xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
michael@0 7
michael@0 8
michael@0 9 <binding id="toolbarbutton-marks" display="xul:button"
michael@0 10 extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton">
michael@0 11 <content disabled="true">
michael@0 12 <xul:panel anonid="panel" hidden="true" type="arrow" class="social-panel"/>
michael@0 13 <xul:image class="toolbarbutton-icon" xbl:inherits="validate,src=image,label"/>
michael@0 14 <xul:label class="toolbarbutton-text" crop="right" flex="1"
michael@0 15 xbl:inherits="value=label,accesskey,crop,wrap"/>
michael@0 16 <xul:label class="toolbarbutton-multiline-text" flex="1"
michael@0 17 xbl:inherits="xbl:text=label,accesskey,wrap"/>
michael@0 18 </content>
michael@0 19 <implementation implements="nsIDOMEventListener, nsIObserver">
michael@0 20 <field name="inMenuPanel">false</field>
michael@0 21
michael@0 22 <property name="panel">
michael@0 23 <getter>
michael@0 24 let widgetGroup = CustomizableUI.getWidget(this.getAttribute("id"));
michael@0 25 let widget = widgetGroup.forWindow(window);
michael@0 26 this.inMenuPanel = widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL;
michael@0 27 if (this.inMenuPanel) {
michael@0 28 widget.node.setAttribute("closemenu", "none");
michael@0 29 return document.getElementById("PanelUI-socialapi");
michael@0 30 }
michael@0 31 return document.getAnonymousElementByAttribute(this, "anonid", "panel");
michael@0 32 </getter>
michael@0 33 </property>
michael@0 34
michael@0 35 <property name="content">
michael@0 36 <getter><![CDATA[
michael@0 37 if (this._frame)
michael@0 38 return this._frame;
michael@0 39 let notificationFrameId = "social-mark-frame-" + this.getAttribute("origin");
michael@0 40 this._frame = SharedFrame.createFrame(
michael@0 41 notificationFrameId, /* frame name */
michael@0 42 this.panel, /* parent */
michael@0 43 {
michael@0 44 "type": "content",
michael@0 45 "mozbrowser": "true",
michael@0 46 "class": "social-panel-frame",
michael@0 47 "id": notificationFrameId,
michael@0 48 "tooltip": "aHTMLTooltip",
michael@0 49 "flex": "1",
michael@0 50 "context": "contentAreaContextMenu",
michael@0 51 "origin": this.getAttribute("origin"),
michael@0 52 "src": "about:blank"
michael@0 53 }
michael@0 54 );
michael@0 55 this._frame.addEventListener("DOMLinkAdded", this);
michael@0 56 this.setAttribute("notificationFrameId", notificationFrameId);
michael@0 57 return this._frame;
michael@0 58 ]]></getter>
michael@0 59 </property>
michael@0 60
michael@0 61 <property name="contentWindow">
michael@0 62 <getter>
michael@0 63 return this.content.contentWindow;
michael@0 64 </getter>
michael@0 65 </property>
michael@0 66
michael@0 67 <property name="contentDocument">
michael@0 68 <getter>
michael@0 69 return this.content.contentDocument;
michael@0 70 </getter>
michael@0 71 </property>
michael@0 72
michael@0 73 <property name="provider">
michael@0 74 <getter>
michael@0 75 return Social._getProviderFromOrigin(this.getAttribute("origin"));
michael@0 76 </getter>
michael@0 77 </property>
michael@0 78
michael@0 79 <property name="isMarked">
michael@0 80 <setter><![CDATA[
michael@0 81 this._isMarked = val;
michael@0 82 let provider = this.provider;
michael@0 83 // we cannot size the image when we apply it via listStyleImage, so
michael@0 84 // use the toolbar image
michael@0 85 let place = CustomizableUI.getPlaceForItem(this);
michael@0 86 val = val && place != "palette";
michael@0 87 let icon = val ? provider.markedIcon : provider.unmarkedIcon;
michael@0 88 let iconURL = icon || provider.icon32URL || provider.iconURL;
michael@0 89 this.setAttribute("image", iconURL);
michael@0 90 ]]></setter>
michael@0 91 <getter>
michael@0 92 return this._isMarked;
michael@0 93 </getter>
michael@0 94 </property>
michael@0 95
michael@0 96 <method name="update">
michael@0 97 <body><![CDATA[
michael@0 98 // update the button for use with the current tab
michael@0 99 let provider = this.provider;
michael@0 100 if (this._dynamicResizer) {
michael@0 101 this._dynamicResizer.stop();
michael@0 102 this._dynamicResizer = null;
michael@0 103 }
michael@0 104 this.content.setAttribute("src", "about:blank");
michael@0 105
michael@0 106 // do we have a savable page loaded?
michael@0 107 let aURI = gBrowser.currentURI;
michael@0 108 this.disabled = !aURI || !(aURI.schemeIs('http') || aURI.schemeIs('https'));
michael@0 109 if (this.disabled) {
michael@0 110 this.isMarked = false;
michael@0 111 } else {
michael@0 112 Social.isURIMarked(provider.origin, aURI, (isMarked) => {
michael@0 113 this.isMarked = isMarked;
michael@0 114 });
michael@0 115 }
michael@0 116
michael@0 117 this.content.setAttribute("origin", provider.origin);
michael@0 118 if (!this.inMenuPanel) {
michael@0 119 let panel = this.panel;
michael@0 120 // if customization is currently happening, we may not have a panel
michael@0 121 // that we can hide
michael@0 122 if (panel.hidePopup) {
michael@0 123 panel.hidePopup();
michael@0 124 panel.hidden = true;
michael@0 125 }
michael@0 126 }
michael@0 127 this.pageData = null;
michael@0 128 ]]></body>
michael@0 129 </method>
michael@0 130
michael@0 131 <method name="loadPanel">
michael@0 132 <parameter name="pageData"/>
michael@0 133 <body><![CDATA[
michael@0 134 let provider = this.provider;
michael@0 135 let panel = this.panel;
michael@0 136 panel.hidden = false;
michael@0 137
michael@0 138 // reparent the iframe if we've been customized to a new location
michael@0 139 if (this.content.parentNode != panel)
michael@0 140 panel.appendChild(this.content);
michael@0 141
michael@0 142 let URLTemplate = provider.markURL;
michael@0 143 this.pageData = pageData || OpenGraphBuilder.getData(gBrowser);
michael@0 144 let endpoint = OpenGraphBuilder.generateEndpointURL(URLTemplate, this.pageData);
michael@0 145
michael@0 146 // setup listeners
michael@0 147 let DOMContentLoaded = (event) => {
michael@0 148 if (event.target != this.contentDocument)
michael@0 149 return;
michael@0 150 this._loading = false;
michael@0 151 this.content.removeEventListener("DOMContentLoaded", DOMContentLoaded, true);
michael@0 152 // add our resizer after the dom is ready
michael@0 153 if (!this.inMenuPanel) {
michael@0 154 let DynamicResizeWatcher = Cu.import("resource:///modules/Social.jsm", {}).DynamicResizeWatcher;
michael@0 155 this._dynamicResizer = new DynamicResizeWatcher();
michael@0 156 this._dynamicResizer.start(this.panel, this.content);
michael@0 157 } else if (this._dynamicResizer) {
michael@0 158 this._dynamicResizer.stop();
michael@0 159 this._dynamicResizer = null;
michael@0 160 }
michael@0 161 // send the opengraph data
michael@0 162 let evt = this.contentDocument.createEvent("CustomEvent");
michael@0 163 evt.initCustomEvent("OpenGraphData", true, true, JSON.stringify(this.pageData));
michael@0 164 this.contentDocument.documentElement.dispatchEvent(evt);
michael@0 165
michael@0 166 let contentWindow = this.contentWindow;
michael@0 167 let markUpdate = function(event) {
michael@0 168 // update the annotation based on this event, then update the
michael@0 169 // icon as well
michael@0 170 this.isMarked = JSON.parse(event.detail).marked;
michael@0 171 let uri = Services.io.newURI(this.pageData.url, null, null);
michael@0 172 if (this.isMarked) {
michael@0 173 Social.markURI(provider.origin, uri);
michael@0 174 } else {
michael@0 175 Social.unmarkURI(provider.origin, uri, () => {
michael@0 176 this.update();
michael@0 177 });
michael@0 178 }
michael@0 179 }.bind(this);
michael@0 180 contentWindow.addEventListener("socialMarkUpdate", markUpdate);
michael@0 181 contentWindow.addEventListener("unload", function unload() {
michael@0 182 contentWindow.removeEventListener("unload", unload);
michael@0 183 contentWindow.removeEventListener("socialMarkUpdate", markUpdate);
michael@0 184 });
michael@0 185 }
michael@0 186 this.content.addEventListener("DOMContentLoaded", DOMContentLoaded, true);
michael@0 187 this._loading = true;
michael@0 188 this.content.setAttribute("src", endpoint);
michael@0 189 ]]></body>
michael@0 190 </method>
michael@0 191
michael@0 192 <method name="openPanel">
michael@0 193 <parameter name="aResetOnClose"/>
michael@0 194 <body><![CDATA[
michael@0 195 let panel = this.panel;
michael@0 196 let frameId = this.getAttribute("notificationFrameId");
michael@0 197
michael@0 198 let wasAlive = SharedFrame.isGroupAlive(frameId);
michael@0 199 SharedFrame.setOwner(frameId, this.content);
michael@0 200
michael@0 201 // Clear dimensions on all browsers so the panel size will
michael@0 202 // only use the selected browser.
michael@0 203 let frameIter = panel.firstElementChild;
michael@0 204 while (frameIter) {
michael@0 205 frameIter.collapsed = (frameIter != this.content);
michael@0 206 frameIter = frameIter.nextElementSibling;
michael@0 207 }
michael@0 208
michael@0 209 // if we're a slice in the hambuger, use that panel instead
michael@0 210 let widgetGroup = CustomizableUI.getWidget(this.getAttribute("id"));
michael@0 211 let widget = widgetGroup.forWindow(window);
michael@0 212 let inMenuPanel = widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL;
michael@0 213 if (inMenuPanel) {
michael@0 214 PanelUI.showSubView("PanelUI-socialapi", widget.node,
michael@0 215 CustomizableUI.AREA_PANEL);
michael@0 216 } else {
michael@0 217 let anchor = document.getAnonymousElementByAttribute(this, "class", "toolbarbutton-icon");
michael@0 218 panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
michael@0 219 this.setAttribute("open", "true");
michael@0 220 }
michael@0 221 if (aResetOnClose) {
michael@0 222 let evName = inMenuPanel ? "ViewHiding": "popuphidden";
michael@0 223 let _hidden = () => {
michael@0 224 panel.removeEventListener(evName, _hidden);
michael@0 225 this.update();
michael@0 226 };
michael@0 227 panel.addEventListener(evName, _hidden, false);
michael@0 228 }
michael@0 229 ]]></body>
michael@0 230 </method>
michael@0 231
michael@0 232 <method name="markCurrentPage">
michael@0 233 <parameter name="aOpenPanel"/>
michael@0 234 <body><![CDATA[
michael@0 235 // we always set the src on click if it has not been set for this tab,
michael@0 236 // but we only want to open the panel if it was previously annotated.
michael@0 237 let openPanel = this.isMarked || aOpenPanel ||
michael@0 238 this.inMenuPanel || !this.provider.haveLoggedInUser();
michael@0 239 let src = this.content.getAttribute("src");
michael@0 240 if (!src || src == "about:blank") {
michael@0 241 this.loadPanel();
michael@0 242 }
michael@0 243 if (openPanel)
michael@0 244 this.openPanel();
michael@0 245 ]]></body>
michael@0 246 </method>
michael@0 247
michael@0 248 <method name="markLink">
michael@0 249 <parameter name="aUrl"/>
michael@0 250 <body><![CDATA[
michael@0 251 if (!aUrl) {
michael@0 252 this.markCurrentPage(true);
michael@0 253 return;
michael@0 254 }
michael@0 255 // initiated form an external source, such as gContextMenu, where
michael@0 256 // pageData is passed into us. In this case, we always load the iframe
michael@0 257 // and show it since the url may not be the browser tab, but an image,
michael@0 258 // link, etc. inside the page. We also "update" the iframe to the
michael@0 259 // previous url when it is closed.
michael@0 260 this.content.setAttribute("src", "about:blank");
michael@0 261 this.loadPanel({ url: aUrl });
michael@0 262 this.openPanel(true);
michael@0 263 ]]></body>
michael@0 264 </method>
michael@0 265
michael@0 266 <method name="dispatchPanelEvent">
michael@0 267 <parameter name="name"/>
michael@0 268 <body><![CDATA[
michael@0 269 let evt = this.contentDocument.createEvent("CustomEvent");
michael@0 270 evt.initCustomEvent(name, true, true, {});
michael@0 271 this.contentDocument.documentElement.dispatchEvent(evt);
michael@0 272 ]]></body>
michael@0 273 </method>
michael@0 274
michael@0 275 <method name="onShown">
michael@0 276 <body><![CDATA[
michael@0 277 // because the panel may be preloaded, we need to size the panel when
michael@0 278 // showing as well as after load
michael@0 279 let sizeSocialPanelToContent = Cu.import("resource:///modules/Social.jsm", {}).sizeSocialPanelToContent;
michael@0 280 if (!this._loading && this.contentDocument &&
michael@0 281 this.contentDocument.readyState == "complete") {
michael@0 282 this.dispatchPanelEvent("socialFrameShow");
michael@0 283 if (!this.inMenuPanel)
michael@0 284 sizeSocialPanelToContent(this.panel, this.content);
michael@0 285 } else {
michael@0 286 let panelBrowserOnload = (e) => {
michael@0 287 this.content.removeEventListener("load", panelBrowserOnload, true);
michael@0 288 this.dispatchPanelEvent("socialFrameShow");
michael@0 289 if (!this.inMenuPanel)
michael@0 290 sizeSocialPanelToContent(this.panel, this.content);
michael@0 291 };
michael@0 292 this.content.addEventListener("load", panelBrowserOnload, true);
michael@0 293 }
michael@0 294 ]]></body>
michael@0 295 </method>
michael@0 296
michael@0 297 <method name="handleEvent">
michael@0 298 <parameter name="aEvent"/>
michael@0 299 <body><![CDATA[
michael@0 300 if (aEvent.eventPhase != aEvent.BUBBLING_PHASE)
michael@0 301 return;
michael@0 302 switch(aEvent.type) {
michael@0 303 case "DOMLinkAdded": {
michael@0 304 // much of this logic is from DOMLinkHandler in browser.js, this sets
michael@0 305 // the presence icon for a chat user, we simply use favicon style
michael@0 306 // updating
michael@0 307 let link = aEvent.originalTarget;
michael@0 308 let rel = link.rel && link.rel.toLowerCase();
michael@0 309 if (!link || !link.ownerDocument || !rel || !link.href)
michael@0 310 return;
michael@0 311 if (link.rel.indexOf("icon") < 0)
michael@0 312 return;
michael@0 313
michael@0 314 let ContentLinkHandler = Cu.import("resource:///modules/ContentLinkHandler.jsm", {}).ContentLinkHandler;
michael@0 315 let uri = ContentLinkHandler.getLinkIconURI(link);
michael@0 316 if (!uri)
michael@0 317 return;
michael@0 318
michael@0 319 // we cannot size the image when we apply it via listStyleImage, so
michael@0 320 // use the toolbar image
michael@0 321 this.setAttribute("image", uri.spec);
michael@0 322 }
michael@0 323 break;
michael@0 324 case "ViewShowing":
michael@0 325 this.onShown();
michael@0 326 break;
michael@0 327 case "ViewHiding":
michael@0 328 this.dispatchPanelEvent("socialFrameHide");
michael@0 329 break;
michael@0 330 }
michael@0 331 ]]></body>
michael@0 332 </method>
michael@0 333
michael@0 334 </implementation>
michael@0 335 <handlers>
michael@0 336 <handler event="popupshown"><![CDATA[
michael@0 337 this.onShown();
michael@0 338 ]]></handler>
michael@0 339 <handler event="popuphidden"><![CDATA[
michael@0 340 this.dispatchPanelEvent("socialFrameHide");
michael@0 341 this.removeAttribute("open");
michael@0 342 ]]></handler>
michael@0 343 <handler event="command"><![CDATA[
michael@0 344 this.markCurrentPage();
michael@0 345 ]]></handler>
michael@0 346 </handlers>
michael@0 347 </binding>
michael@0 348
michael@0 349 </bindings>

mercurial