Last Comment Bug 747805 - Kuma: optional IRC widget
: Kuma: optional IRC widget
Status: NEW
[pm-wanted][LOE:10+]
:
Product: Mozilla Developer Network
Classification: Other
Component: Wiki pages (show other bugs)
: unspecified
: x86 Mac OS X
-- enhancement with 2 votes (vote)
: ---
Assigned To: Nobody; OK to take it and work on it
:
:
Mentors:
Depends on: 1120531
Blocks:
  Show dependency treegraph
 
Reported: 2012-04-22 17:05 PDT by Janet Swisher
Modified: 2016-10-24 01:24 PDT (History)
16 users (show)
See Also:
QA Whiteboard:
Iteration: ---
Points: ---


Attachments
Example from en.flossmanual.net of an IRC widget in a CMS editing UI. (159.71 KB, image/png)
2012-04-22 17:05 PDT, Janet Swisher
no flags Details
Analytics developer.mozilla.org (production) Top Events 20140713-20140812.pdf (173.99 KB, application/vnd.pdf)
2014-08-13 09:33 PDT, Luke Crouch [:groovecoder]
no flags Details
Mockup of chat button in footer (196.47 KB, image/png)
2014-10-30 09:12 PDT, aravind
no flags Details
Contribution placement (87.63 KB, image/png)
2015-06-17 12:48 PDT, Stephanie Hobson [:shobson]
no flags Details

Description User image Janet Swisher 2012-04-22 17:05:18 PDT
Created attachment 617357 [details]
Example from en.flossmanual.net of an IRC widget in a CMS editing UI.

Feature request: Add an IRC widget embedded in MDN. This could be similar to the (former?) mibbit widget on air.mozilla.org, but for #devmo. It should be opened from a button or link (something like "Chat about MDN content"). 

The purpose of this is to enable more community interaction directly in the site. However, it should be optional, so it doesn't get in the way of the reading and editing experience for those who don't want it.

FLOSS Manuals has a widget like this in the "Edit" UI (see attachment). It even generates an IRC nick based on the user's login ID. I'm not sure whether this is built into Booktype (the platform that FM runs on), or is a customization by FM.
Comment 1 User image Eric Shepherd [:sheppy] 2012-04-22 17:24:16 PDT
We used to have (and still have, although the skin doesn't hook into it anymore, so it doesn't work) a feature that would look at the tags on the page and include a box saying "Discuss this on IRC" with a list of links to IRC channels (#devmo for tag "MDC", #developers for tags like "Build Documentation", etc). Was really awesome. We need that working again.
Comment 2 User image Janet Swisher 2013-01-24 19:32:53 PST
Just to be clear: Are you suggesting combining the idea of tags-based display of IRC channels with the idea of an embedded IRC widget? I.e., suggest channels to join, and then open a widget into the selected channel?

I thought we discussed that idea in the MDN planning meeting earlier this month, and I mentioned it on the Mozillians mailing list. April Morone made an important point in response: Once you open an IRC session, it should persist until you close that session, even if you move to a different MDN page (that doesn't have that tag).
Comment 3 User image Eric Shepherd [:sheppy] 2013-01-25 07:50:33 PST
(In reply to Janet Swisher from comment #2)
> Just to be clear: Are you suggesting combining the idea of tags-based
> display of IRC channels with the idea of an embedded IRC widget? I.e.,
> suggest channels to join, and then open a widget into the selected channel?
> 
> I thought we discussed that idea in the MDN planning meeting earlier this
> month, and I mentioned it on the Mozillians mailing list. April Morone made
> an important point in response: Once you open an IRC session, it should
> persist until you close that session, even if you move to a different MDN
> page (that doesn't have that tag).

This is what I would like exactly. Use the page's tags to figure out appropriate IRC channels to offer to connect the user to. The idea of persistence is a good one.
Comment 4 User image Janet Swisher 2013-01-25 08:18:59 PST
Accordingly, removed "#devmo" from the summary.
Comment 5 User image April Morone 2013-01-25 14:06:28 PST
(In reply to Eric Shepherd [:sheppy] from comment #3)
> (In reply to Janet Swisher from comment #2)
> > Just to be clear: Are you suggesting combining the idea of tags-based
> > display of IRC channels with the idea of an embedded IRC widget? I.e.,
> > suggest channels to join, and then open a widget into the selected channel?
> > 
> > I thought we discussed that idea in the MDN planning meeting earlier this
> > month, and I mentioned it on the Mozillians mailing list. April Morone made
> > an important point in response: Once you open an IRC session, it should
> > persist until you close that session, even if you move to a different MDN
> > page (that doesn't have that tag).
> 
> This is what I would like exactly. Use the page's tags to figure out
> appropriate IRC channels to offer to connect the user to. The idea of
> persistence is a good one.

Eric,I agree with you about this.  Let me look into this and then fix this bug.  I will then use the appropriate tags and then see about having it added into the site.
April Morone
Comment 6 User image Luke Crouch [:groovecoder] 2013-01-28 17:41:46 PST
Good to see some action on this bug. April, you can start by forking https://github.com/mozilla/kuma and going thru https://github.com/mozilla/kuma/blob/master/docs/installation-vagrant.rst to set up a local dev box. Email me or catch me on IRC (groovecoder) as needed.
Comment 7 User image April Morone 2013-01-28 19:16:40 PST
(In reply to Luke Crouch [:groovecoder] from comment #6)
> Good to see some action on this bug. April, you can start by forking
> https://github.com/mozilla/kuma and going thru
> https://github.com/mozilla/kuma/blob/master/docs/installation-vagrant.rst to
> set up a local dev box. Email me or catch me on IRC (groovecoder) as needed.

Luke,
     I will fork kuma and then will set up a local dev box.  I will then catch you on IRC, or e-mail you if you aren't available at the time on IRC.
April Morone
Comment 8 User image April Morone 2013-05-22 13:48:53 PDT
So far, have foumd issues with which even Luke couldn't fix )and he'd good at development.  The issue is the following:

curl 'http://developer-local.allizom.org'

The problem is that it had trouble connecting to the host, as well as kept saying at other times of that the SSL connection times out.  So, I did as Luke then instructed me to do of going to http://developer-local.allizom.org, that it should set the port to 443, and of turning off curl SSL verification via the -k command, but I got an error message about the site being down.  Not sure what to do about that or if I should try to move forward in the process, anyway, since I got the Kuma welcome message after moving forward in the dev environment setup passed curl 'https://developer-local.allizom.org', past vagrant ssh command.  Ideas are welcome, please.  :)
April Morone
Comment 9 User image Luke Crouch [:groovecoder] 2013-05-22 14:26:14 PDT
The welcome message should have instructions for starting the web server:

~/bin/go-tmux.sh
Comment 10 User image April Morone 2013-05-22 15:44:32 PDT
(In reply to Luke Crouch [:groovecoder] from comment #9)
> The welcome message should have instructions for starting the web server:
> 
> ~/bin/go-tmux.sh

It does, hon.  :)  I will follow these instructions.  Thank you.  :)
April Morone
Comment 11 User image April Morone 2013-05-28 05:46:34 PDT
I may have aofund a solution to this bug.  Read below, as well as my forked repo file of mozilla/Kuma repo.
April Morone

To build a Widget that will seem to stay open even when users go to other areas of the site, straight forward AJAX (XMLHttpRequest) is needed.  Straight forward AJAX is used so that the IM and chat sidebars stay open, instead of closing out out when users go to different pages of the websites.  The reason this is used is to allow for the sending and receiving of information without the need to refresh the page.  To update the address bar, Javascript History API is used. And to avoid any problems with the widget itself losing info when reloaded, try instead of something like the following on each page of


*//DOJO uses AJAX and Javascript for its UI widgets.  And, its implementation of DTL matches Django.  The code for creating custom widgets in websites is below.//
   <p>dojo Understanding_WidgetBase: <a href="http://dojotoolkit.org/documentation/tutorials/1.9/understanding_widgetbase/</a></p>
   
*//Download DOJO.  Then read the documentation about it to familiarize yourself with it.  If you are already very familiar with javascript and AJAX, then it might be easier for you to grasp this that implements AJAX and Javascript.  A Javacript Widget is below for you to see how a widget would be in Javascript code for widget UI.

The Javascript Widget UI code is below is used as an example, here, to show you what is basically need for a UI widget.

/*!
 * jQuery UI Widget 1.9.2
 * http://jqueryui.com
 *
 * Copyright 2012 jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/jQuery.widget/
 */
(function( $, undefined ) {

var uuid = 0,
  slice = Array.prototype.slice,
  _cleanData = $.cleanData;
$.cleanData = function( elems ) {
	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
		try {
			$( elem ).triggerHandler( "remove" );
		// http://bugs.jquery.com/ticket/8235
		} catch( e ) {}
	}
	_cleanData( elems );
};

$.widget = function( name, base, prototype ) {
	var fullName, existingConstructor, constructor, basePrototype,
		namespace = name.split( "." )[ 0 ];

	name = name.split( "." )[ 1 ];
	fullName = namespace + "-" + name;

	if ( !prototype ) {
		prototype = base;
		base = $.Widget;
	}

	// create selector for plugin
	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
		return !!$.data( elem, fullName );
	};

	$[ namespace ] = $[ namespace ] || {};
	existingConstructor = $[ namespace ][ name ];
	constructor = $[ namespace ][ name ] = function( options, element ) {
		// allow instantiation without "new" keyword
		if ( !this._createWidget ) {
			return new constructor( options, element );
		}

		// allow instantiation without initializing for simple inheritance
		// must use "new" keyword (the code above always passes args)
		if ( arguments.length ) {
			this._createWidget( options, element );
		}
	};
	// extend with the existing constructor to carry over any static properties
	$.extend( constructor, existingConstructor, {
		version: prototype.version,
		// copy the object used to create the prototype in case we need to
		// redefine the widget later
		_proto: $.extend( {}, prototype ),
		// track widgets that inherit from this widget in case this widget is
		// redefined after a widget inherits from it
		_childConstructors: []
	});

	basePrototype = new base();
	// we need to make the options hash a property directly on the new instance
	// otherwise we'll modify the options hash on the prototype that we're
	// inheriting from
	basePrototype.options = $.widget.extend( {}, basePrototype.options );
	$.each( prototype, function( prop, value ) {
		if ( $.isFunction( value ) ) {
			prototype[ prop ] = (function() {
				var _super = function() {
						return base.prototype[ prop ].apply( this, arguments );
					},
					_superApply = function( args ) {
						return base.prototype[ prop ].apply( this, args );
					};
				return function() {
					var __super = this._super,
						__superApply = this._superApply,
						returnValue;

					this._super = _super;
					this._superApply = _superApply;

					returnValue = value.apply( this, arguments );

					this._super = __super;
					this._superApply = __superApply;

					return returnValue;
				};
			})();
		}
	});
	constructor.prototype = $.widget.extend( basePrototype, {
		// TODO: remove support for widgetEventPrefix
		// always use the name + a colon as the prefix, e.g., draggable:start
		// don't prefix for widgets that aren't DOM-based
		widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
	}, prototype, {
		constructor: constructor,
		namespace: namespace,
		widgetName: name,
		// TODO remove widgetBaseClass, see #8155
		widgetBaseClass: fullName,
		widgetFullName: fullName
	});

	// If this widget is being redefined then we need to find all widgets that
	// are inheriting from it and redefine all of them so that they inherit from
	// the new version of this widget. We're essentially trying to replace one
	// level in the prototype chain.
	if ( existingConstructor ) {
		$.each( existingConstructor._childConstructors, function( i, child ) {
			var childPrototype = child.prototype;

			// redefine the child widget using the same prototype that was
			// originally used, but inherit from the new version of the base
			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
		});
		// remove the list of existing child constructors from the old constructor
		// so the old child constructors can be garbage collected
		delete existingConstructor._childConstructors;
	} else {
		base._childConstructors.push( constructor );
	}

	$.widget.bridge( name, constructor );
};

$.widget.extend = function( target ) {
	var input = slice.call( arguments, 1 ),
		inputIndex = 0,
		inputLength = input.length,
		key,
		value;
	for ( ; inputIndex < inputLength; inputIndex++ ) {
		for ( key in input[ inputIndex ] ) {
			value = input[ inputIndex ][ key ];
			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
				// Clone objects
				if ( $.isPlainObject( value ) ) {
					target[ key ] = $.isPlainObject( target[ key ] ) ?
						$.widget.extend( {}, target[ key ], value ) :
						// Don't extend strings, arrays, etc. with objects
						$.widget.extend( {}, value );
				// Copy everything else by reference
				} else {
					target[ key ] = value;
				}
			}
		}
	}
	return target;
};

$.widget.bridge = function( name, object ) {
	var fullName = object.prototype.widgetFullName || name;
	$.fn[ name ] = function( options ) {
		var isMethodCall = typeof options === "string",
			args = slice.call( arguments, 1 ),
			returnValue = this;

		// allow multiple hashes to be passed on init
		options = !isMethodCall && args.length ?
			$.widget.extend.apply( null, [ options ].concat(args) ) :
			options;

		if ( isMethodCall ) {
			this.each(function() {
				var methodValue,
					instance = $.data( this, fullName );
				if ( !instance ) {
					return $.error( "cannot call methods on " + name + " prior to initialization; " +
						"attempted to call method '" + options + "'" );
				}
				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
				}
				methodValue = instance[ options ].apply( instance, args );
				if ( methodValue !== instance && methodValue !== undefined ) {
					returnValue = methodValue && methodValue.jquery ?
						returnValue.pushStack( methodValue.get() ) :
						methodValue;
					return false;
				}
			});
		} else {
			this.each(function() {
				var instance = $.data( this, fullName );
				if ( instance ) {
					instance.option( options || {} )._init();
				} else {
					$.data( this, fullName, new object( options, this ) );
				}
			});
		}

		return returnValue;
	};
};

$.Widget = function( /* options, element */ ) {};
$.Widget._childConstructors = [];

$.Widget.prototype = {
	widgetName: "widget",
	widgetEventPrefix: "",
	defaultElement: "<div>",
	options: {
		disabled: false,

		// callbacks
		create: null
	},
	_createWidget: function( options, element ) {
		element = $( element || this.defaultElement || this )[ 0 ];
		this.element = $( element );
		this.uuid = uuid++;
		this.eventNamespace = "." + this.widgetName + this.uuid;
		this.options = $.widget.extend( {},
			this.options,
			this._getCreateOptions(),
			options );

		this.bindings = $();
		this.hoverable = $();
		this.focusable = $();

		if ( element !== this ) {
			// 1.9 BC for #7810
			// TODO remove dual storage
			$.data( element, this.widgetName, this );
			$.data( element, this.widgetFullName, this );
			this._on( true, this.element, {
				remove: function( event ) {
					if ( event.target === element ) {
						this.destroy();
					}
				}
			});
			this.document = $( element.style ?
				// element within the document
				element.ownerDocument :
				// element is window or document
				element.document || element );
			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
		}

		this._create();
		this._trigger( "create", null, this._getCreateEventData() );
		this._init();
	},
	_getCreateOptions: $.noop,
	_getCreateEventData: $.noop,
	_create: $.noop,
	_init: $.noop,

	destroy: function() {
		this._destroy();
		// we can probably remove the unbind calls in 2.0
		// all event bindings should go through this._on()
		this.element
			.unbind( this.eventNamespace )
			// 1.9 BC for #7810
			// TODO remove dual storage
			.removeData( this.widgetName )
			.removeData( this.widgetFullName )
			// support: jquery <1.6.3
			// http://bugs.jquery.com/ticket/9413
			.removeData( $.camelCase( this.widgetFullName ) );
		this.widget()
			.unbind( this.eventNamespace )
			.removeAttr( "aria-disabled" )
			.removeClass(
				this.widgetFullName + "-disabled " +
				"ui-state-disabled" );

		// clean up events and states
		this.bindings.unbind( this.eventNamespace );
		this.hoverable.removeClass( "ui-state-hover" );
		this.focusable.removeClass( "ui-state-focus" );
	},
	_destroy: $.noop,

	widget: function() {
		return this.element;
	},

	option: function( key, value ) {
		var options = key,
			parts,
			curOption,
			i;

		if ( arguments.length === 0 ) {
			// don't return a reference to the internal hash
			return $.widget.extend( {}, this.options );
		}

		if ( typeof key === "string" ) {
			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
			options = {};
			parts = key.split( "." );
			key = parts.shift();
			if ( parts.length ) {
				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
				for ( i = 0; i < parts.length - 1; i++ ) {
					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
					curOption = curOption[ parts[ i ] ];
				}
				key = parts.pop();
				if ( value === undefined ) {
					return curOption[ key ] === undefined ? null : curOption[ key ];
				}
				curOption[ key ] = value;
			} else {
				if ( value === undefined ) {
					return this.options[ key ] === undefined ? null : this.options[ key ];
				}
				options[ key ] = value;
			}
		}

		this._setOptions( options );

		return this;
	},
	_setOptions: function( options ) {
		var key;

		for ( key in options ) {
			this._setOption( key, options[ key ] );
		}

		return this;
	},
	_setOption: function( key, value ) {
		this.options[ key ] = value;

		if ( key === "disabled" ) {
			this.widget()
				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
				.attr( "aria-disabled", value );
			this.hoverable.removeClass( "ui-state-hover" );
			this.focusable.removeClass( "ui-state-focus" );
		}

		return this;
	},

	enable: function() {
		return this._setOption( "disabled", false );
	},
	disable: function() {
		return this._setOption( "disabled", true );
	},

	_on: function( suppressDisabledCheck, element, handlers ) {
		var delegateElement,
			instance = this;

		// no suppressDisabledCheck flag, shuffle arguments
		if ( typeof suppressDisabledCheck !== "boolean" ) {
			handlers = element;
			element = suppressDisabledCheck;
			suppressDisabledCheck = false;
		}

		// no element argument, shuffle and use this.element
		if ( !handlers ) {
			handlers = element;
			element = this.element;
			delegateElement = this.widget();
		} else {
			// accept selectors, DOM elements
			element = delegateElement = $( element );
			this.bindings = this.bindings.add( element );
		}

		$.each( handlers, function( event, handler ) {
			function handlerProxy() {
				// allow widgets to customize the disabled handling
				// - disabled as an array instead of boolean
				// - disabled class as method for disabling individual parts
				if ( !suppressDisabledCheck &&
						( instance.options.disabled === true ||
							$( this ).hasClass( "ui-state-disabled" ) ) ) {
					return;
				}
				return ( typeof handler === "string" ? instance[ handler ] : handler )
					.apply( instance, arguments );
			}

			// copy the guid so direct unbinding works
			if ( typeof handler !== "string" ) {
				handlerProxy.guid = handler.guid =
					handler.guid || handlerProxy.guid || $.guid++;
			}

			var match = event.match( /^(\w+)\s*(.*)$/ ),
				eventName = match[1] + instance.eventNamespace,
				selector = match[2];
			if ( selector ) {
				delegateElement.delegate( selector, eventName, handlerProxy );
			} else {
				element.bind( eventName, handlerProxy );
			}
		});
	},

	_off: function( element, eventName ) {
		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
		element.unbind( eventName ).undelegate( eventName );
	},

	_delay: function( handler, delay ) {
		function handlerProxy() {
			return ( typeof handler === "string" ? instance[ handler ] : handler )
				.apply( instance, arguments );
		}
		var instance = this;
		return setTimeout( handlerProxy, delay || 0 );
	},

	_hoverable: function( element ) {
		this.hoverable = this.hoverable.add( element );
		this._on( element, {
			mouseenter: function( event ) {
				$( event.currentTarget ).addClass( "ui-state-hover" );
			},
			mouseleave: function( event ) {
				$( event.currentTarget ).removeClass( "ui-state-hover" );
			}
		});
	},

	_focusable: function( element ) {
		this.focusable = this.focusable.add( element );
		this._on( element, {
			focusin: function( event ) {
				$( event.currentTarget ).addClass( "ui-state-focus" );
			},
			focusout: function( event ) {
				$( event.currentTarget ).removeClass( "ui-state-focus" );
			}
		});
	},

	_trigger: function( type, event, data ) {
		var prop, orig,
			callback = this.options[ type ];

		data = data || {};
		event = $.Event( event );
		event.type = ( type === this.widgetEventPrefix ?
			type :
			this.widgetEventPrefix + type ).toLowerCase();
		// the original event may come from any element
		// so we need to reset the target on the new event
		event.target = this.element[ 0 ];

		// copy original event properties over to the new event
		orig = event.originalEvent;
		if ( orig ) {
			for ( prop in orig ) {
				if ( !( prop in event ) ) {
					event[ prop ] = orig[ prop ];
				}
			}
		}

		this.element.trigger( event, data );
		return !( $.isFunction( callback ) &&
			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
			event.isDefaultPrevented() );
	}
};

$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
		if ( typeof options === "string" ) {
			options = { effect: options };
		}
		var hasOptions,
			effectName = !options ?
				method :
				options === true || typeof options === "number" ?
					defaultEffect :
					options.effect || defaultEffect;
		options = options || {};
		if ( typeof options === "number" ) {
			options = { duration: options };
		}
		hasOptions = !$.isEmptyObject( options );
		options.complete = callback;
		if ( options.delay ) {
			element.delay( options.delay );
		}
		if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
			element[ method ]( options );
		} else if ( effectName !== method && element[ effectName ] ) {
			element[ effectName ]( options.duration, options.easing, callback );
		} else {
			element.queue(function( next ) {
				$( this )[ method ]();
				if ( callback ) {
					callback.call( element[ 0 ] );
				}
				next();
			});
		}
	};
});

// DEPRECATED
if ( $.uiBackCompat !== false ) {
	$.Widget.prototype._getCreateOptions = function() {
		return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
	};
}

})( jQuery );


*//You could make widget use just one channel name for the entire site so that all users on the website use the same channel. You can do so by providing a channel name option when creating the PusherChatWidget object://
$(function() {     
  var pusher = new Pusher('YOUR_APP_KEY');
  var chatWidget = new PusherChatWidget(pusher, {
    chatEndPoint: 'pusher-realtime-chat-widget/src/php/chat.php',
    channelName: 'site-wide-chat-channel'
  });
});

*//Now, here is the DOJO code for the dijit _WidgetBase infrastructure and Widget code.//

DOJO: Getters and Setters

// for the field "foo" in your widget:
 
// custom getter
_getFooAttr: function(){ /* do something and return a value */ },
 
//  custom setter
_setFooAttr: function(value){ /* do something to set a value */ }

/ assume that the widget instance is "myWidget":
 
// get the value of "foo":
var value = myWidget.get("foo");
 
// set the value of "foo":
myWidget.set("foo", someValue);

// assume our field is called "value":
 
_setValueAttr: function(value){
    this.onChange(this.value, value);
    this._set("value", value);
},
 
// a function designed to work with dojo/on
onChange: function(oldValue, newValue){ }

*//Owning handles DOJO code that helps with registering handles as "owned" by the Widget.//

this.own(
    on(someDomNode, "click", lang.hitch(this, "myOnClickHandler)"),
    aspect.after(someObject, "someFunc", lang.hitch(this, "mySomeFuncHandler)"),
    topic.subscribe("/some/topic", function(){ ... }),
    ...
);

*//DOJO code for customizing a Widget//

define([
    "dojo/_base/declare",
    "dijit/_WidgetBase",
    "dijit/_TemplatedMixin",
    "dojo/text!./templates/SomeWidget.html"
], function(declare, _WidgetBase, _TemplatedMixin, template) {
 
    return declare([_WidgetBase, _TemplatedMixin], {
        templateString: template
        //  your custom code goes here
    });
 
});

*//The containerNode attach point//

<div class="${baseClass}">
    <div class="${baseClass}Title" data-dojo-attach-point="titleNode"
            data-dojo-attach-event="ondijitclick:_onClick"></div>
    <div>And our container:</div>
    <div class="${baseClass}Container"
            data-dojo-attach-point="containerNode"></div>
</div>

*//It could be used in declarative markup like this//

<div data-dojo-type="demo/SomeWidget"
        data-dojo-props="title: 'Our Some Widget'">
    <p>This is arbitrary content!</p>
    <p>More arbitrary content!</p>
</div>

*//When the Dojo parser traverses the document, it will find our example widget and instantiate it — and as part of that instantiation, any markup inside the widget will be appended to the containerNode. When the widget is finished with its startup, the resulting DOM will look like this://

<div id="demo_SomeWidget_0" class="someWidgetBase">
    <div class="someWidgetTitle">Our Some Widget</div>
    <div class="someWidgetContainer">
        <p>This is arbitrary content!</p>
        <p>More arbitrary content!</p>
    </div>
</div>

*//Event Attchment DOM Fragment//

data-dojo-attach-event="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick"

*//After your Widget has been instantiated and the DOM fragment created from your template, the Dijit template system will automatically then go through any attached event definitions and "auto-magically" wire these events (using dojo/on) from the resulting DOM and your widget object — making it incredibly simple to wire your visual representation to your controlling code.  Plus, when those event handlers are fired, the same arguments normally passed by the native DOM event mechanism will be passed along to your widget's handler so that you get to have and will have full access to what the browser is reporting.  You'll want to use want to use the dijit/_OnDijitClickMixin which adds in a modified event that supports more functionalty than the standard DOM onclick event.  So, you'll need to modify your Widget declaration//

define([
    "dojo/_base/declare",
    "dijit/_WidgetBase",
    "dijit/_OnDijitClickMixin",
    "dijit/_TemplatedMixin",
    "dojo/text!./templates/SomeWidget.html"
], function(declare, _WidgetBase, _OnDijitClickMixin, _TemplatedMixin,
        template) {
 
    return declare([_WidgetBase, _OnDijitClickMixin, _TemplatedMixin], {
        templateString: template
        //  any custom code goes here
    });
 
});

*//And then your widget template//

<div class="${baseClass}">
    <div class="${baseClass}Title"
        data-dojo-attach-point="titleNode"
        data-dojo-attach-event="ondijitclick:_onClick"></div>
    <div>And our container:</div>
    <div class="${baseClass}Container"
        data-dojo-attach-point="containerNode"></div>
</div>

*//If wanting to create a more complex widget from templates for MDN, you can do so through the use of the _WidgetsInTemplateMixin mixin, which tells the template system that your template has other widgets in it and to instantiate them when your widget is instantiated.//
*//An example, always including the Dijit button.  Modify the declaration to always include the Dijit button.//

define([
    "dojo/_base/declare",
    "dijit/_WidgetBase",
    "dijit/_OnDijitClickMixin",
    "dijit/_TemplatedMixin",
    "dijit/_WidgetsInTemplateMixin",
    "dijit/form/Button",
    "dojo/text!./templates/SomeWidget.html"
], function(declare, _WidgetBase, _OnDijitClickMixin, _TemplatedMixin,
            _WidgetsInTemplateMixin, Button, template) {
 
    return declare("example.SomeWidget", [_WidgetBase, _OnDijitClickMixin,
        _TemplatedMixin, _WidgetsInTemplateMixin
    ], {
        templateString: template
        //  your custom code goes here
    });
 
});

*//Then, create a template like...//

<div class="${baseClass}" data-dojo-attach-point="focusNode"
        data-dojo-attach-event="ondijitclick:_onClick"
        role="menuitem" tabIndex="-1">
    <div data-dojo-type="dijit/form/Button"
        data-dojo-attach-point="buttonWidget">
        My Button
    </div>
    <span data-dojo-attach-point="containerNode"></span>
</div>

*//This, as I understand it, is the code to create a widget that uses AJAX that can make the widget stay open as users go throughout the website.  And if using DOJO for this widget, there could be a better chance of the creation and then the implementation working because of how it works with django.//
Comment 12 User image David Walsh :davidwalsh 2013-05-28 09:00:23 PDT
I'll bring this up in as far as redesign, but before I do, is this something where we'd like to attempt a Facebook-style "on every page" chat widget, or do we want to put a "chat" window next to select tag icons, or simply dock the like screenshot?  We should flesh this out more before I talk to the redesign team.  Sheppy, Janet -- thoughts?

If we want to make this tag-specific, someone should draft tag->IRC room matches within this ticket.
Comment 13 User image Eric Shepherd [:sheppy] 2013-05-28 10:50:57 PDT
(In reply to David Walsh :davidwalsh from comment #12)
> I'll bring this up in as far as redesign, but before I do, is this something
> where we'd like to attempt a Facebook-style "on every page" chat widget, or
> do we want to put a "chat" window next to select tag icons, or simply dock
> the like screenshot?  We should flesh this out more before I talk to the
> redesign team.  Sheppy, Janet -- thoughts?
> 
> If we want to make this tag-specific, someone should draft tag->IRC room
> matches within this ticket.

I would like something tag-specific; we had something like that back on Mindtouch for a while before a Mindtouch update broke the setup we had devised, where a DekiScript template we wrote would look at the page's tags and add a list of appropriate IRC channel links to the page.

What I'd like is to have a set of IRC channel buttons or links for the relevant channels included on the page based on the tags, and have those buttons open a box or panel (which, I don't really care) for that channel. Ideally, if the user has an IRC client installed, that would be opened instead.
Comment 14 User image April Morone 2013-05-28 11:27:02 PDT
I almost did that, too, earlier.  Then thought that everyone wanted something like a chat widget that worked like Facebook's does so that even if going to a different part of the site, they still are trying to carry on a conversation about a previous topic while multitasking, they can do so like that.  But, if it could be easier to add links into the webpages, that could work, too.  I could go ahead and do that, as well.
Comment 15 User image April Morone 2013-05-28 11:30:27 PDT
But, if you would like me to do so, do you want me to do so upon signing in through web browser into the MDN site, or via Terminal of my Ubuntu 12.04LTS OS Terminal on my desktop computer?  The latter, I hit a snag on being able to continue to add pages through terminal after entering into Kuma and starting up Django that I also.  It coyuld be easier to make alterations to the webpages the other way until I figure that part out to get through that part.  Unless you know how to get around that.  :)  If you do, I am all ears, as the saying goes.  :)
Comment 16 User image Eric Shepherd [:sheppy] 2013-05-28 11:40:48 PDT
(In reply to BlackJadedHeart from comment #14)
> I almost did that, too, earlier.  Then thought that everyone wanted
> something like a chat widget that worked like Facebook's does so that even
> if going to a different part of the site, they still are trying to carry on
> a conversation about a previous topic while multitasking, they can do so
> like that.  But, if it could be easier to add links into the webpages, that
> could work, too.  I could go ahead and do that, as well.

Sounds like since there's no way to determine whether or not the user has an IRC client, we just need to do something in-browser. How that's presented, I don't know. Personally, I would prefer a separate window for it, but perhaps that's not the best way to present the UX by default to the average user.
Comment 17 User image April Morone 2013-05-28 11:54:40 PDT
(In reply to Eric Shepherd [:sheppy] from comment #16)
> (In reply to BlackJadedHeart from comment #14)
> > I almost did that, too, earlier.  Then thought that everyone wanted
> > something like a chat widget that worked like Facebook's does so that even
> > if going to a different part of the site, they still are trying to carry on
> > a conversation about a previous topic while multitasking, they can do so
> > like that.  But, if it could be easier to add links into the webpages, that
> > could work, too.  I could go ahead and do that, as well.
> 
> Sounds like since there's no way to determine whether or not the user has an
> IRC client, we just need to do something in-browser. How that's presented, I
> don't know. Personally, I would prefer a separate window for it, but perhaps
> that's not the best way to present the UX by default to the average user.

I know all about how it is presented (my hobby is building websites, etc).  Therefor, I think it could be best to implement it as a UI widget, instead.  And because I cannot explain it well enough about UI widgets, mI will use Microsoft's wording, "The web browser is the platform, JavaScript is the language, and various JavaScript libraries represent key parts of the environment."  I imagine that if we use AJAX, as well, and the nmanipulate the browser, using history.replaceState() instead of history.pushState(), we could get the effect we want from the widget to force it to not close out when users go to other areas of the MDN site while using the UI widget.  What do you think?
Comment 18 User image April Morone 2013-05-28 11:58:48 PDT
(replaceState() modifies the current history entry instead of creating a new one).  Maybe that even further lessens the chances of the widget closing out before the users are ready to close out the widget.
Comment 19 User image April Morone 2013-05-28 12:22:04 PDT
(In reply to Eric Shepherd [:sheppy] from comment #16)
> (In reply to BlackJadedHeart from comment #14)
> > I almost did that, too, earlier.  Then thought that everyone wanted
> > something like a chat widget that worked like Facebook's does so that even
> > if going to a different part of the site, they still are trying to carry on
> > a conversation about a previous topic while multitasking, they can do so
> > like that.  But, if it could be easier to add links into the webpages, that
> > could work, too.  I could go ahead and do that, as well.
> 
> Sounds like since there's no way to determine whether or not the user has an
> IRC client, we just need to do something in-browser. How that's presented, I
> don't know. Personally, I would prefer a separate window for it, but perhaps
> that's not the best way to present the UX by default to the average user.

(replaceState() modifies the current history entry instead of creating a new one).  Maybe that even further lessens the chances of the widget closing out before the users are ready to close out the widget.

Dijit is Dojo’s UI Library, and lives as a separate namespace dijit. Dijit requires Dojo Core and Dojo Base.
Comment 20 User image April Morone 2013-11-13 01:11:24 PST
(In reply to Eric Shepherd [:sheppy] from comment #16)
> (In reply to BlackJadedHeart from comment #14)
> > I almost did that, too, earlier.  Then thought that everyone wanted
> > something like a chat widget that worked like Facebook's does so that even
> > if going to a different part of the site, they still are trying to carry on
> > a conversation about a previous topic while multitasking, they can do so
> > like that.  But, if it could be easier to add links into the webpages, that
> > could work, too.  I could go ahead and do that, as well.
> 
> Sounds like since there's no way to determine whether or not the user has an
> IRC client, we just need to do something in-browser. How that's presented, I
> don't know. Personally, I would prefer a separate window for it, but perhaps
> that's not the best way to present the UX by default to the average user.

I've created PHP chat and an AJAX JavaScrip app, as well as a Firefox add-on of which I will soon see if I can link to a chat app.  The AJAX JavaScript app is probably the better app to implement.  I still will need to revise it.  But, I have the basics of it done.  After I can see about how to link the chat to where the FF browser add-on can link it, I will send all that info to you all.  Alternatively, I can create the DOJO AJAX chat now that I have the time to do so, if you'd rather that way of it if that could be better.
April Morone
Comment 21 User image Luke Crouch [:groovecoder] 2013-11-13 07:48:14 PST
Thanks April. If you can, please send a pull request with any code to the kuma repository, or put prototype/example code up on your own github repository so we can see it there.
Comment 22 User image April Morone 2013-11-13 14:36:08 PST
(In reply to Luke Crouch [:groovecoder] from comment #21)
> Thanks April. If you can, please send a pull request with any code to the
> kuma repository, or put prototype/example code up on your own github
> repository so we can see it there.

Okay.  I will.  :)
Comment 23 User image April Morone 2013-11-13 20:00:21 PST
(In reply to Luke Crouch [:groovecoder] from comment #21)
> Thanks April. If you can, please send a pull request with any code to the
> kuma repository, or put prototype/example code up on your own github
> repository so we can see it there.

Actually, before I do so, may I work on this some more?  Having issues with the PHP chat and want to also revise the code for the AJAX JavaScript chat before sending it onward.
Comment 24 User image April Morone 2013-11-13 20:01:24 PST
(want it all to be as good as possible before sending it onward).
Comment 25 User image Eric Shepherd [:sheppy] 2013-11-15 09:38:36 PST
We can also consider using https://github.com/stephenmcd/gnotty -- this is a Django project specifically for integrating a site with IRC.
Comment 26 User image April Morone 2013-11-15 19:46:16 PST
(In reply to Eric Shepherd [:sheppy] from comment #25)
> We can also consider using https://github.com/stephenmcd/gnotty -- this is a
> Django project specifically for integrating a site with IRC.

Good idea.  I will check it out and see about this.  :)
Comment 27 User image April Morone 2013-11-15 19:53:25 PST
(In reply to Eric Shepherd [:sheppy] from comment #25)
> We can also consider using https://github.com/stephenmcd/gnotty -- this is a
> Django project specifically for integrating a site with IRC.

So, create DOJO AJAX Jquery files and add them into that Git repo of the link of which you specified, recently, so that it than can be implemented by someone other than me (trying to make sure I understand, fully).
Comment 28 User image Janet Swisher 2014-07-10 12:03:38 PDT
Has anyone looked at using http://scrollback.io/ for this? You can see it in use on http://mozillaindia.org/

Priyanka Nag (in cc) works for this company, so she might be a technical resource.
Comment 29 User image Luke Crouch [:groovecoder] 2014-07-14 06:08:22 PDT
It looks cool. 

Priyanka - I tried to link an "mdn" room to our #mdn channel on irc.mozilla.org and got:

"This IRC account is already linked with another room. Try a different server."

Is there already a scrollback.io room linked to #mdn channel?
Comment 30 User image Priyanka Nag [:priynag] 2014-08-12 04:27:49 PDT
I am sorry. This bug somehow went un-noticed by me for sometime. 

The #mdn channel was linked to another room on Scrollback. We are unlinking the channel from the other room. You should now be able to link the mdn room to the #mdn channel. Let me know if any other issue comes up. 

Apologies again for the late reply.
Comment 31 User image Luke Crouch [:groovecoder] 2014-08-12 14:48:32 PDT
:sheppy - "The IRC channel operator needs to type "/invite scrollback #mdn" in the IRC channel to complete the process."
Comment 32 User image Luke Crouch [:groovecoder] 2014-08-12 14:52:37 PDT
Looks like someone got to it:

https://scrollback.io/mdn?tab=info

Priyanka, I'm having trouble getting the widget to work in a jsfiddle:

http://jsfiddle.net/nyL6r8x8/
Comment 33 User image Priyanka Nag [:priynag] 2014-08-13 03:56:37 PDT
Hey Luke,

If you instead put the script in the html section within the <script> tag, it seems to be working fine.

http://jsfiddle.net/nyL6r8x8/1/ 

Something going wrong with our Script against the way JSFiddle handles JavaScript probably. We are looking into it and will try and modify our script for that.
Comment 34 User image Luke Crouch [:groovecoder] 2014-08-13 07:08:14 PDT
Very cool! :janet - how does that jsfiddle widget look to you?

:hoosteeno - this should get back into the prioritization queue now that we have a potential solution to re-evaluate.
Comment 35 User image Justin Crawford [:hoosteeno] [:jcrawford] 2014-08-13 07:48:51 PDT
Very cool widget! Some questions from someone just catching up to this conversation...

* What problem is this solving?
* Do we know whether there is demand for it?
* Can we run any kind of experiment to learn whether folks will use it?
* Where is it proposed: On every page for every site visitor? Or for subsets of both, to be specified?
* What is the LOE of this?
Comment 36 User image Eric Shepherd [:sheppy] 2014-08-13 08:00:31 PDT
(In reply to Justin Crawford [:hoosteeno] from comment #35)
> Very cool widget! Some questions from someone just catching up to this
> conversation...
> 
> * What problem is this solving?

Goal: To make it easier for newcomers to join the conversation. Most people don't know what IRC is, and certainly don't have a client. IRC is a very nerd-heavy technology. Let's help others join us!

> * Do we know whether there is demand for it?

The demand is presumed for two reasons:

1. We do get email/tweets asking how to get in, or what "IRC" is.

2. Given that we know that IRC is nerd-heavy and not commonly used, it's easy to surmise that most people are unable to join our conversation.

> * Can we run any kind of experiment to learn whether folks will use it?

Probably. We could A/B test inclusion of this widget.

> * Where is it proposed: On every page for every site visitor? Or for subsets
> of both, to be specified?

This I don't know.

Personally, what I would like to do is offer support for a "Join the conversation" button in tandem with specific tags (we did this for a while once, with irc:// links generated automatically based on tags -- if the page was tagged "XPCOM" the #developers channel was linked to, for instance). So in the sidebar or something, you'd see a set of links to open channels based on the tags on the page.

> * What is the LOE of this?

LOE? Load of Excrement? Loss of Excitement? Land of Enchantment?
Comment 37 User image Luke Crouch [:groovecoder] 2014-08-13 09:33:01 PDT
(In reply to Justin Crawford [:hoosteeno] from comment #35)

> * Do we know whether there is demand for it?

I checked GA for clicks on "IRC" outbound links [attached] and I learned some things:

* Most people click the web links (i.e., "Learn more" or links to mibbit web client - not the irc:// links that join straight to the channel)
* Our own #mdn channel only gets 0.57% of IRC clicks, compared to #introduction (to Mozilla coding) getting 23%, #js getting 6%, #devtools getting 2%, etc.
 
> * Can we run any kind of experiment to learn whether folks will use it?

Of course. :) We can waffle the code that adds the IRC widget, and we can certainly measure any clicks that activate the widget.

We *might* be able measure focus/hover over the containing element, but we can't measure interactions *inside* the widget since it's loaded into an iframe.

> * Where is it proposed: On every page for every site visitor? Or for subsets
> of both, to be specified?

Based on the GA data, I propose 2 iterations:

1. Global #mdn widget
2. In certain zones, replace the #mdn widget with a widget connected to the relevant IRC channel for the topic

> * What is the LOE of this?

1. LOE: 10 to add widget code and to style it appropriately with the site design (if possible)
2. LOE+10 to:
  1. Create the scrollback.io channels
  2. Add a map of MDN zones/topics to scrollback.io channels
  3. Update our scrollback.io widget code to draw the right widget on the right page

:davidwalsh - does that seem like a sane estimate?

Priyanka - one thing I couldn't tell from the jsfiddle is whether the widget's state would persist as the user navigates across MDN? (https://bugzilla.mozilla.org/show_bug.cgi?id=747805#c2)
Comment 38 User image Luke Crouch [:groovecoder] 2014-08-13 09:33:36 PDT
Created attachment 8472429 [details]
Analytics developer.mozilla.org (production) Top Events 20140713-20140812.pdf
Comment 39 User image Priyanka Nag [:priynag] 2014-08-13 09:47:11 PDT
Answering Luke's question here: 
whether the widget's state would persist as the user navigates across MDN?
Ans: If its added on a particular page, it will remain on the page and if its added on the header which is being called on all pages, it will be present on all pages. (If that is what you meant).

An example of the successful implementation of the Scrollback widget can be seen here (the widget here is added only on the home page): http://mozillaindia.org/

Another example where I have added the widget in the header that is being called from all pages: http://priynag.blogspot.in

I am not sure if I have answered you correctly. Please let me know if you have more doubts.
Comment 40 User image Justin Crawford [:hoosteeno] [:jcrawford] 2014-08-13 09:53:26 PDT
> 1. Global #mdn widget

I'm wondering if there is any value (for signal/noise purposes) to gating this with login. We could, for example, issue a CTA to login/create an account to use the on-site widget.
Comment 41 User image David Walsh :davidwalsh 2014-08-13 10:10:02 PDT
I see a "theme" parameter is set, but has anyone used this enough to know if we can create our own themes inside scrollback.io?  Realize this loads an iframe and since the iframe content isn't on our domain, we can't inject stylesheets or anything for specific styling.
Comment 42 User image Janet Swisher 2014-08-13 11:03:22 PDT
(In reply to Justin Crawford [:hoosteeno] from comment #40)
> > 1. Global #mdn widget
> 
> I'm wondering if there is any value (for signal/noise purposes) to gating
> this with login. We could, for example, issue a CTA to login/create an account to use the on-site widget.

I'm not sure a global #mdn widget has value at all. It's likely to attract people asking any question about anything, much as we found when we had a UserVoice forum linked on every page that was supposed to be only for MDN feedback.

However, I agree with putting the IRC widget behind a login, to cut down on IRC spam, and encourage sign-ups. It's another account benefit.
Comment 43 User image April Morone 2014-08-13 11:06:12 PDT
(In reply to Janet Swisher from comment #42)
> (In reply to Justin Crawford [:hoosteeno] from comment #40)
> > > 1. Global #mdn widget
> > 
> > I'm wondering if there is any value (for signal/noise purposes) to gating
> > this with login. We could, for example, issue a CTA to login/create an account to use the on-site widget.
> 
> I'm not sure a global #mdn widget has value at all. It's likely to attract
> people asking any question about anything, much as we found when we had a
> UserVoice forum linked on every page that was supposed to be only for MDN
> feedback.
> 
> However, I agree with putting the IRC widget behind a login, to cut down on
> IRC spam, and encourage sign-ups. It's another account benefit.

I agree.  This sounds like a secure way.
Comment 44 User image Priyanka Nag [:priynag] 2014-08-13 12:48:24 PDT
(In reply to David against comment #41)

Whatever modification is needed with the Scrollback widget, can be done. I can get you connected to the UI developer of Scrollback who can make the changes as per required.

Also, the Scrollback codebase is available here: https://github.com/scrollback/scrollback (Just incase if you wanna take a look)
Comment 45 User image Janet Swisher 2014-08-15 14:49:45 PDT
(In reply to Luke Crouch [:groovecoder] from comment #34)
> Very cool! :janet - how does that jsfiddle widget look to you?

Looks good to me. I assume we'd want to theme it consistently with MDN.
Comment 46 User image Luke Crouch [:groovecoder] 2014-10-30 07:38:32 PDT
Consolidating some of the previous comments:

* We will start with the widget behind sign-in (via waffle flag)
* The first iteration is to increase MDN users discussing MDN docs
* Another iteration will potentially map document tags to the best Mozilla IRC rooms for discussing those technologies.

Now, what's the first problem to address? Giving site readers a room to discuss docs without editing? Or giving site editors a room to discuss edits while they work? Or something else?

E.g., should we only show the widget on the "Edit Document" page, or on all pages?
Comment 47 User image David Walsh :davidwalsh 2014-10-30 07:39:35 PDT
I suppose the new + edit + translate pages would be a good start; in the future, maybe it could be opened up to all-wiki.  Doing the latter, I believe, would lead to more support/help requests which we don't want.
Comment 48 User image Eric Shepherd [:sheppy] 2014-10-30 09:02:29 PDT
(In reply to Luke Crouch [:groovecoder] from comment #46)
> Consolidating some of the previous comments:
> 
> * We will start with the widget behind sign-in (via waffle flag)
> * The first iteration is to increase MDN users discussing MDN docs
> * Another iteration will potentially map document tags to the best Mozilla
> IRC rooms for discussing those technologies.
> 
> Now, what's the first problem to address? Giving site readers a room to
> discuss docs without editing? Or giving site editors a room to discuss edits
> while they work? Or something else?
> 
> E.g., should we only show the widget on the "Edit Document" page, or on all
> pages?

The point here isn't to give writers a way to talk; it's to give readers a way to quickly join conversations related to the topic they're reading about. If they're on a page about WebRTC, there should be a way to quickly jump into #media and talk to the WebRTC folks.

If they're reading about add-ons, there should be quick access to #extdev.

Etc.
Comment 49 User image aravind 2014-10-30 09:12:34 PDT
Created attachment 8514343 [details]
Mockup of chat button in footer

Mockup of chat button in the page footer. The Scrollback widget will be hidden until the button is clicked.

The button could be displayed when a page tag maps to an IRC channel. In the (probably) rare situation where page has multiple mapped tags, multiple buttons may be shown.

I'm not sure how the waffle flag works (new to Kuma) but I’m guessing the button can say “Sign in to chat” instead of being disabled or hidden?

The signed in user’s name can be passed to Scrollback as one of the initialization parameters, and it will try to use that nick while connecting to IRC.

Persistence across pages: Scrollback will remember the username across page loads, but not the scroll position or typed (but not sent) text.

If Facebook-like persistence is necessary, it can be implemented in Kuma (fully client-side, using LocalStorage) with a moderate amount of effort.
Comment 50 User image Eric Shepherd [:sheppy] 2014-10-30 09:28:26 PDT
(In reply to aravind from comment #49)

> Mockup of chat button in the page footer. The Scrollback widget will be
> hidden until the button is clicked.

I love it.

> The button could be displayed when a page tag maps to an IRC channel. In the
> (probably) rare situation where page has multiple mapped tags, multiple
> buttons may be shown.

I actually don't think this will be rare at all. An article about how to use JavaScript to alter CSS styling on an HTML document might be tagged with JavaScript, HTML, and CSS, among other things.

> If Facebook-like persistence is necessary, it can be implemented in Kuma
> (fully client-side, using LocalStorage) with a moderate amount of effort.

I don't think that's necessary, although I think conversations that are going on should keep going on while a tab is in the background, if the IRC widget is open.
Comment 51 User image Priyanka Nag [:priynag] 2014-11-05 23:12:46 PST
Do we have a final plan on how and where we are planning to implement the Scrollback widget on the MDN platform? We can send in a few more mockups based on that, if required. Also, if there is anything else we can provide from our end right now, I would be more than happy to take it up :)
Comment 52 User image Janet Swisher 2014-11-06 12:26:45 PST
In short, I don't think so. I don't think anyone is assigned to work on it yet (either staff or volunteer), and nor have I seen a timeline for it.

Justin, what's your view?
Comment 53 User image aravind 2014-11-18 01:42:02 PST
If we have clarity on how we want to proceed, I can work on adding this to Kuma.

Is the mockup (comment #49) a good representation of where we want to go?
Comment 54 User image Justin Crawford [:hoosteeno] [:jcrawford] 2014-11-18 07:53:03 PST
I think the mockup is a solid place to start building the widget, but I think we're not ready to build the widget. 

1. Which visitors to the site will have access to IRC? (comment 49, comment 46, comment 43, comment 42 indicate the feature should be implemented for "signed in"; comment 48 seems to suggest the feature is being implemented for "all")
2. Where will visitors see the option to join IRC? (comment 47 indicates the feature should be seen in edit mode; comment 48 suggests it should be seen in reading mode)
3. What IRC channels will user have the option to join? (comment 1, comment 3, comment 37, comment 48 suggest any number of channels; comment 37 suggests a global #mdn widget; comment 42 suggests no global #mdn widget)
4. Will those IRC channels be ready to support MDN visitors? (it could be hundreds of thousands per month, it could be fewer than ten, depending on the answers to the above questions)

Without clarity on these we cannot proceed. 

Furthermore, without more clarity on the above questions, it is difficult to understand what priority this bug should have. Is it helping all of MDN's readers? Is it helping only readers with accounts who are signed in? Is it helping only readers with accounts who are signed in looking at certain sections of the site? Or is it helping editors? 

Finally, if the intention really is to embed a Q&A opportunity in MDN content to help millions of MDN readers, I think we might have much greater success more tightly integrating with StackOverflow. It is more asynchronous and it scales better to those numbers.

To help us answer the questions raised above, I built ... wait for it ... an etherpad! If you have participated in the conversation above then you must have some opinion about how this should be built. Please go to the etherpad and let's flesh this opportunity out.

https://devengage.etherpad.mozilla.org/irc-widget-20141118
Comment 55 User image Eric Shepherd [:sheppy] 2014-11-18 08:57:55 PST
My answers/opinions for :hoosteeno's questions (there's room for debate on some of these, I'm sure). I'll go fill out my thoughts on the etherpad in a moment.

1. IMO, all users should be able to access IRC. Users who are logged in should automatically be hooked into IRC using their username as their nick (in fact, ideally, we'd do stuff with nickserv to reserve their nick). Other users would have to enter a nick or accept a randomly-generated one.

Yes, we'd need to warn the folks that are key players in each channel that they may see a major influx of users. But we don't actually know yet how much impact this will have. And I imagine that some of the users will be people who already use IRC to communicate but find it more convenient to pop in from the docs as-needed.

2. IRC access should always be available, regardless of whether you're reading or editing. I do think that when editing, #mdn should be added to the list of channels you have to choose from.

3. There should be a list of channels you can choose from, based on the tags on the page. For example, an article about using <video> element in an extension should be tagged with "Extensions" and "Media" among other things; these two tags would, respectively, result in adding "#extdev" and "#media" to the list of recommended IRC channels.

4. I don't really know how many people we'll get. Could be tons, could be practically nobody. We can try it and find out; that's likely the only way to get this insight.p If it's "too successful" we can investigate options from pulling the plug to creating new, separate IRC channels for these support venues, and/or staffing them on a schedule with official reps.

I believe this feature would help all MDN users. Most people do not have an IRC client, and don't even know what IRC is. Having an embedded widget to allow people to talk to each other (and to pros) about Web technology would be an enormous enabler for them to learn good habits and techniques, and to answer tough questions, thereby reducing the odds that someone will throw up their hands in disgust and swear off web development.
Comment 56 User image April Morone 2014-11-18 12:20:26 PST
I like Sheppy's idea.  And, I also wonder if we could also  do something like having a Captcha added to the widget for people to type in the Captcha code so that spammers nor bots won't be added to the chats of bots that aren't purposesly added by owners of the IRC channels.
April Morone
Comment 57 User image April Morone 2014-11-18 12:25:01 PST
I meant of also adding about that I wonder if we could add Captcha to the widget to prevent not only spammers but also bots not added by Mozilla from getting added to chat.
Comment 58 User image April Morone 2014-11-18 12:26:50 PST
**I meant of also adding about that I wonder if we could add Captcha to the widget to prevent not only spammers but also bots not added by Mozilla from getting SENT to chat, I meant.  So sorry for my typing error, before.
Comment 59 User image Priyanka Nag [:priynag] 2014-11-18 22:35:29 PST
(In reply to April Morone from comment #58)
> **I meant of also adding about that I wonder if we could add Captcha to the
> widget to prevent not only spammers but also bots not added by Mozilla from
> getting SENT to chat, I meant.  So sorry for my typing error, before.

Yes. Adding a captha to the widget is very much possible.
Comment 60 User image April Morone 2014-11-19 02:56:40 PST
(In reply to Priyanka Nag from comment #59)
> (In reply to April Morone from comment #58)
> > **I meant of also adding about that I wonder if we could add Captcha to the
> > widget to prevent not only spammers but also bots not added by Mozilla from
> > getting SENT to chat, I meant.  So sorry for my typing error, before.
> 
> Yes. Adding a captha to the widget is very much possible.

Okay.  Cool that it is possible to do so.  Would you all be willing to add this to the widget?
Comment 61 User image aravind 2014-11-23 06:48:17 PST
I think the primary concerns are around the IRC channels being unequipped to handle a large increase in users with questions. Justin's comment at the bottom of the etherpad hints at a solution:

> I think we need to be  very, very careful not to implement this, or even suggest it as a  "helpline" for MDN users.

We can convey clearly that this is a community discussion space rather than a helpdesk. The typical MDN user is a web developer who would otherwise ask their questions on a community forum (e.g. StackOverflow) which has no paid staff and provide no guarantee of help; I don’t believe they will suddenly begin to demand 24x7 service on MDN.

We could even show a sentence or two explaining this, alongside the Captcha.
Comment 62 User image Eric Shepherd [:sheppy] 2014-11-24 06:28:26 PST
(In reply to aravind from comment #61)
> We can convey clearly that this is a community discussion space rather than
> a helpdesk. The typical MDN user is a web developer who would otherwise ask
> their questions on a community forum (e.g. StackOverflow) which has no paid
> staff and provide no guarantee of help; I don’t believe they will suddenly
> begin to demand 24x7 service on MDN.

Precisely.

> We could even show a sentence or two explaining this, alongside the Captcha.

There could also be something displayed in the widget space itself, reminding people not to expect 24/7 instantaneous service (or, in fact, any service at all). Likewise, we should include information in our page(s) that talk about our community and how to get help details about not just the fact that they can't get 24/7 help, but why.
Comment 63 User image April Morone 2014-11-25 12:32:06 PST
(In reply to Eric Shepherd [:sheppy] from comment #62)
> (In reply to aravind from comment #61)
> > We can convey clearly that this is a community discussion space rather than
> > a helpdesk. The typical MDN user is a web developer who would otherwise ask
> > their questions on a community forum (e.g. StackOverflow) which has no paid
> > staff and provide no guarantee of help; I don’t believe they will suddenly
> > begin to demand 24x7 service on MDN.
> 
> Precisely.
> 
> > We could even show a sentence or two explaining this, alongside the Captcha.
> 
> There could also be something displayed in the widget space itself,
> reminding people not to expect 24/7 instantaneous service (or, in fact, any
> service at all). Likewise, we should include information in our page(s) that
> talk about our community and how to get help details about not just the fact
> that they can't get 24/7 help, but why.

I guess that that could work.  In my first event as a new rep, I held a meeting about troubleshooting contributor issues which included the topic about web development=a topic which held Janet's interest (according to Janet in the video-recorded meeting).  In that particular meeting, she stated that she thinks the chat should be placed in an area where not just everyone can access it because than we might get more randomness, but that maybe we could have it in more specific areas of MDN (Janet, if I didn't state that well enough, nor as accurate as I should have about the MDN chat widget placement, please correct me).  :)
Comment 64 User image Janet Swisher 2014-11-25 12:56:09 PST
Specifically, I think a staged approach to adding topics and channels would be wise. And that "contributing to Mozilla code" topics might be a good place to start, since users in that area would probably have more targeted questions than those in open-Web areas. We could learn from that experience before adding the widget to more general areas.
Comment 65 User image Justin Crawford [:hoosteeno] [:jcrawford] 2014-11-25 13:52:36 PST
I agree that this feature needs an experiment before we commit to a permanent or site-wide rollout. Right now, the numbers around IRC-via-MDN simply don't justify investing much in making MDN into an IRC client. This bug desperately needs a champion who will work through the experimental phase everyone is suggesting to produce some data that will make it an obvious win.

Specifically, someone needs to do these things:

A) Design an experiment
* Choose sections of the site the experiment will appear on
* Choose which IRC channels the experiment will serve (and discuss with their "regulars")
* Decide how long the experiment will run
* Figure out how to measure user uptake of the feature
* Figure out how to measure user satisfaction with the feature

B) Work with aravind or other volunteer engineers to:
* Build the feature
  ** behind a waffle flag
  ** including GA tracking
* Send kuma pull request for staff engineering to review & deploy
* Run the experiment

C) Compile/review factors
* Experiment results: usage
* Experiment results: satisfaction
* Context: how it impacts MDN/Mozilla KPIs

This is roughly the process that we're planning to push new feature requests through in 2015. With the information above in hand, it's easy to make a go/no-go decision about the enhancement. Without that information, it's very challenging. 

We're not staffed right now to do this for all 277 enhancement requests in the backlog. Since this bug is so popular, I'd like to encourage someone who feels passionately about it to jump in.
Comment 66 User image April Morone 2014-11-25 23:59:51 PST
(In reply to Janet Swisher from comment #64)
> Specifically, I think a staged approach to adding topics and channels would
> be wise. And that "contributing to Mozilla code" topics might be a good
> place to start, since users in that area would probably have more targeted
> questions than those in open-Web areas. We could learn from that experience
> before adding the widget to more general areas.

Janet,
Thank you for giving me more of the exact info you'd meant and stated.  :)  I understand what you mean, here, and I think your idea a good one to implement.  :)  Doing this in stages makes a lot of sense.  :)
Comment 67 User image Adrian Aichner [:anaran] 2014-11-28 10:15:40 PST
How about qwebirc for integration in the browser?

I've been using
http://webchat.mozilla-tunisia.org:9090/
off and on an still like it when I'm not in thunderbird.

See also http://docs.couchdb.org/en/1.6.1/contents.html which uses it for the IRC link in the sidebar.
Comment 68 User image April Morone 2014-11-28 17:54:10 PST
(In reply to adrian.aichner from comment #67)
> How about qwebirc for integration in the browser?
> 
> I've been using
> http://webchat.mozilla-tunisia.org:9090/
> off and on an still like it when I'm not in thunderbird.
> 
> See also http://docs.couchdb.org/en/1.6.1/contents.html which uses it for
> the IRC link in the sidebar.

That particular chat client has been brought up, before.  It seems it maybe could be a good choice.
Comment 69 User image April Morone 2014-11-28 17:55:13 PST
I had hoped to have had the chat I built ready, but logically, it is not, yet.  To many projects at one time and other stuff going on that kept me away from revision of it.  So, this might be a more logical choice, at this time.
Comment 70 User image Luke Crouch [:groovecoder] 2014-12-20 12:46:19 PST
:hoosteeno, Janet, or Priyanka - can any of you re-visit https://bugzilla.mozilla.org/show_bug.cgi?id=747805#c65 and fill it in from our meeting at Mozlandia?
Comment 71 User image Priyanka Nag [:priynag] 2014-12-31 12:14:48 PST
Meeting notes from Portlandia:

[1] We'll display the Scrollback widget on "Contribute to MDN" pages i.e. on all the meta docs.
[2] The widget will initially only open into the #mdn channel on irc.mozilla.org
[4] The widget will be deployed for at least a month so we can see how people respond
[5] We will measure the success of this widget in 2 ways...
  1. The raw number of people who open it up and interact with it
  2. We will capture the username of named users who open it up and interact with it, and will follow up with them with a very simple survey
[6] We will use the outcome of our measurements to determine whether any further action is needed
[7] The engineering and experiment will be contributor-led efforts; MDN devs will support with code reviews, deploys, waffle settings, and other MDN staff will do what they can to keep it unblocked.
[8] When someone is logged on to MDN, the person will not need to separate login to the Scrollback widget. The username will be automatically carried forward to the widget.
[9] We are also working around the idea of adding some wrapper around the widget which can clearly say that the chat is not supposed to be treated as a customer service provider but rather as a community discussion channel.
Comment 72 User image Justin Crawford [:hoosteeno] [:jcrawford] 2015-01-05 08:04:27 PST
Has anyone worked through a review of Scrollback's privacy policy and terms? If not, that is a preliminary step that should block this bug.
Comment 73 User image Janet Swisher 2015-01-08 07:02:14 PST
AFAIK, no, so yes, we need a review. Do you want to file a Legal bug, or shall I?
Comment 74 User image Justin Crawford [:hoosteeno] [:jcrawford] 2015-01-12 10:35:04 PST
Project review bug filed: bug 1120531.
Comment 75 User image Jannis Leidel [:jezdez] 2015-01-13 11:19:04 PST
Hi all, I've just looked at the PR https://github.com/mozilla/kuma/pull/2992 and I'm afraid I need some clarifications and raise some red flags here while looking through this ticket.

1. From looking at the scrollback.io source code (https://github.com/scrollback/scrollback) I'm having trouble knowing if the site is going to handle the load MDN creates. There is zero documentation and the project is less than a year old. I can't find a continuous test setup online so don't know if the tests pass. In short: I'm very skeptical about the software quality of scrollback.io.

2. (Assuming the IRC bridge runs on scrollback.io servers) Have we checked with the irc.mozilla.org people if the number of sign-ins from the scrollback.io IRC bridge can be handled? Will there be throttling happening for scrollback.io IPs? How are we going to handle operational feedback, e.g. if the widget breaks? Are we going to have a contract in place to make clear when and where to ask for support?

3. What's the status about transmitting PII to a 3rd party? According to scrollback.io's privacy page (http://web.scrollback.io/privacy/) the IP addresses are stored even if users aren't logged into a scrollback.io account. In other words, that sounds as if we're automatically transmitting any of our user's IP to scrollback.io.
Comment 76 User image Luke Crouch [:groovecoder] 2015-01-13 11:38:47 PST
As context for #1 and #2: the first experiment will put the widget on docs/MDN pages, which get 13k page-views per month, average of 440 page-views per day = 18 per hour. :jezdez - should we block this experiment on testing the scalability of scrollback.io and/or irc.mozilla.org?

I assume operational feedback will go into the #mdn & #mdndev IRC channels. On the MDN side we'll be able to disable the waffle flag at any time to kill the widget. Priyanka - how can the MDN devs and writers get support from scrollback.io?

In our websites privacy policy ([1] linked from MDN footer), we tell users that we use 3rd party services that use cookies, IP addresses, and online data tools in relation to our websites.

[1] https://www.mozilla.org/en-US/privacy/websites/
Comment 77 User image Jannis Leidel [:jezdez] 2015-01-13 11:56:52 PST
(In reply to Luke Crouch [:groovecoder] from comment #76)
> As context for #1 and #2: the first experiment will put the widget on
> docs/MDN pages, which get 13k page-views per month, average of 440
> page-views per day = 18 per hour. :jezdez - should we block this experiment
> on testing the scalability of scrollback.io and/or irc.mozilla.org?

Yes

> I assume operational feedback will go into the #mdn & #mdndev IRC channels.
> On the MDN side we'll be able to disable the waffle flag at any time to kill
> the widget.

IMO this is a no-go since we're not OPs people in #mdn or #mdndev. The difference to other 3rd party services that we use which makes me uncomfortable is that the widget is visible to users and may be misleading.

Priyanka - how can the MDN devs and writers get support from
> scrollback.io?
> 
> In our websites privacy policy ([1] linked from MDN footer), we tell users
> that we use 3rd party services that use cookies, IP addresses, and online
> data tools in relation to our websites.
> 
> [1] https://www.mozilla.org/en-US/privacy/websites/

Does scrollback.io respect the DNT header?
Comment 78 User image aravind 2015-01-13 20:24:50 PST
(In reply to Jannis Leidel [:jezdez] from comment #77)
> (In reply to Luke Crouch [:groovecoder] from comment #76)
> > As context for #1 and #2: the first experiment will put the widget on
> > docs/MDN pages, which get 13k page-views per month, average of 440
> > page-views per day = 18 per hour. :jezdez - should we block this experiment
> > on testing the scalability of scrollback.io and/or irc.mozilla.org?
> 
> Yes

Our daily traffic ranges between 600 and 1600 new connections an hour, but we have handled peaks of 7,500 requests an hour without incident. Luke had said 18 MDN page loads per hour, which is not a significant increase.

For completeness I must point out that only users who click the “Chat about MDN” button will connect to Scrollback; assuming that 5% do (this is a high estimate) we expect less than one connection per hour from this experiment.

May I su


> > I assume operational feedback will go into the #mdn & #mdndev IRC channels.
> > On the MDN side we'll be able to disable the waffle flag at any time to kill
> > the widget.
> 
> IMO this is a no-go since we're not OPs people in #mdn or #mdndev. The
> difference to other 3rd party services that we use which makes me
> uncomfortable is that the widget is visible to users and may be misleading.
> 

This is one of the things amalantony mentioned in his first comment on the pull request (where he asked for it to be marked incomplete). As discussed earlier in this thread, the idea is that when Scrollback is first displayed, a message on the lines of “Welcome to the MDN community’s chat room. Please follow the [community guidelines] (link).” will be displayed, which the user must dismiss to reveal the message input box.

> Priyanka - how can the MDN devs and writers get support from
> > scrollback.io?

1) Priyanka’s day job is at Scrollback, email her.
2) I work at Scrollback, email me [aravind@scrollback.io]
3) There’s a support address [support@scrollback.io]

> > 
> > In our websites privacy policy ([1] linked from MDN footer), we tell users
> > that we use 3rd party services that use cookies, IP addresses, and online
> > data tools in relation to our websites.
> > 
> > [1] https://www.mozilla.org/en-US/privacy/websites/
> 
> Does scrollback.io respect the DNT header?

We have no infrastructure to track signed-out users across sessions. We do not serve advertizing. Correct me if I’m wrong, but I believe this covers it?
Comment 79 User image aravind 2015-01-13 20:40:00 PST
Apologies for replying in the wrong order.

(In reply to Jannis Leidel [:jezdez] from comment #75)
> Hi all, I've just looked at the PR https://github.com/mozilla/kuma/pull/2992
> and I'm afraid I need some clarifications and raise some red flags here
> while looking through this ticket.
> 
> 1. From looking at the scrollback.io source code
> (https://github.com/scrollback/scrollback) I'm having trouble knowing if the
> site is going to handle the load MDN creates. There is zero documentation
> and the project is less than a year old. I can't find a continuous test
> setup online so don't know if the tests pass. In short: I'm very skeptical
> about the software quality of scrollback.io.

The project is around 20 months old (it was in another repo, askabt/scrollback, earlier).

We currently use nightly build and not CI because of a large number of slow selenium tests. Here’s yesterday’s test report: https://stage.scrollback.io/s/tmp/email-150113.html

You will note that there are a few test failures: The only unit tests that failed are for features not yet implemented. The only selenium tests that failed are for IE10, and they pass in manual testing which indicates this is a DOM selector issue.

> 
> 2. (Assuming the IRC bridge runs on scrollback.io servers) Have we checked
> with the irc.mozilla.org people if the number of sign-ins from the
> scrollback.io IRC bridge can be handled? Will there be throttling happening
> for scrollback.io IPs? How are we going to handle operational feedback, e.g.
> if the widget breaks? Are we going to have a contract in place to make clear
> when and where to ask for support?

Over a dozen channels on irc.mozilla.org use Scrollback on their websites already. (e.g. mozillaindia.org, mozillaphilippines.org). Our IP is whitelisted for around 100 simultaneous connections (IIRC) by the ircops, and were told to raise another bug to request a further increase when it became necessary.

This happened over a year ago, and I’m afraid I can’t find the bug anymore.

> 
> 3. What's the status about transmitting PII to a 3rd party? According to
> scrollback.io's privacy page (http://web.scrollback.io/privacy/) the IP
> addresses are stored even if users aren't logged into a scrollback.io
> account. In other words, that sounds as if we're automatically transmitting
> any of our user's IP to scrollback.io.

1. Only users who click on the button to begin chatting make a connection to Scrollback.
2. Unless they register an account at Scrollback, their IP is only stored in access logs which gets purged in 3-4 months.
Comment 80 User image aravind 2015-01-15 07:29:52 PST
Correction: The connection limit for scrollback at irc.mozilla.org is 50 [bug 901009, bug 937126] but I believe they will be open to increasing it as required.
Comment 81 User image Priyanka Nag [:priynag] 2015-01-21 00:54:00 PST
Any update?
Comment 82 User image Eric Shepherd [:sheppy] 2015-04-01 12:51:22 PDT
How's it coming?
Comment 83 User image Stephanie Hobson [:shobson] 2015-06-17 12:48:49 PDT
Created attachment 8623853 [details]
Contribution placement

Given that the discussion documented in comment 71 says this is just to go on pages under https://developer.mozilla.org/docs/MDN/ How's this for placement and wording?
Comment 84 User image Janet Swisher 2015-06-17 15:06:57 PDT
Looks good!

s/will open/opens/

Could also link "IRC" to https://wiki.mozilla.org/IRC

That aside, please proceed!

Note You need to log in before you can comment on or make changes to this bug.