adium-1.4 2682:6beac534df5b: Update Renkoo message style for the...
commits at adium.im
commits at adium.im
Fri Oct 30 16:57:49 UTC 2009
details: http://hg.adium.im/adium-1.4/rev/6beac534df5b
revision: 2682:6beac534df5b
author: Stephen Holt <sholt at adium.im>
date: Fri Oct 30 12:57:26 2009 -0400
Update Renkoo message style for the new coalescing template html.
Requires overloading a few methods from the Template.html file, but no longer Template.html itself.
Smooth scroll and fade-in should work as before. Confirm, plz.
diffs (677 lines):
diff -r 594253d97431 -r 6beac534df5b Resources/Message Styles/renkoo.AdiumMessageStyle/Contents/Resources/Footer.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/Message Styles/renkoo.AdiumMessageStyle/Contents/Resources/Footer.html Fri Oct 30 12:57:26 2009 -0400
@@ -0,0 +1,231 @@
+<script type="text/javascript">
+ isDebug = false;
+
+ // Fade interval in milliseconds
+ // Make this larger if you experience performance issues
+ Fadomatic.INTERVAL_MILLIS = 50;
+
+ // Creates a fader
+ // element - The element to fade
+ // speed - The speed to fade at, from 0.0 to 100.0
+ // initialOpacity (optional, default 100) - element's starting opacity, 0 to 100
+ // minOpacity (optional, default 0) - element's minimum opacity, 0 to 100
+ // maxOpacity (optional, default 0) - element's minimum opacity, 0 to 100
+ function Fadomatic (element, rate, initialOpacity, minOpacity, maxOpacity) {
+ this._element = element;
+ this._intervalId = null;
+ this._rate = rate;
+ this._isFadeOut = true;
+
+ // Set initial opacity and bounds
+ // NB use 99 instead of 100 to avoid flicker at start of fade
+ this._minOpacity = 0;
+ this._maxOpacity = 99;
+ this._opacity = 99;
+
+ if (typeof minOpacity != 'undefined') {
+ if (minOpacity < 0) {
+ this._minOpacity = 0;
+ } else if (minOpacity > 99) {
+ this._minOpacity = 99;
+ } else {
+ this._minOpacity = minOpacity;
+ }
+ }
+
+ if (typeof maxOpacity != 'undefined') {
+ if (maxOpacity < 0) {
+ this._maxOpacity = 0;
+ } else if (maxOpacity > 99) {
+ this._maxOpacity = 99;
+ } else {
+ this._maxOpacity = maxOpacity;
+ }
+
+ if (this._maxOpacity < this._minOpacity) {
+ this._maxOpacity = this._minOpacity;
+ }
+ }
+
+ if (typeof initialOpacity != 'undefined') {
+ if (initialOpacity > this._maxOpacity) {
+ this._opacity = this._maxOpacity;
+ } else if (initialOpacity < this._minOpacity) {
+ this._opacity = this._minOpacity;
+ } else {
+ this._opacity = initialOpacity;
+ }
+ }
+
+ // See if we're using W3C opacity, MSIE filter, or just
+ // toggling visiblity
+ if(typeof element.style.opacity != 'undefined') {
+
+ this._updateOpacity = this._updateOpacityW3c;
+
+ } else if(typeof element.style.filter != 'undefined') {
+
+ // If there's not an alpha filter on the element already,
+ // add one
+ if (element.style.filter.indexOf("alpha") == -1) {
+
+ // Attempt to preserve existing filters
+ var existingFilters="";
+ if (element.style.filter) {
+ existingFilters = element.style.filter+" ";
+ }
+ element.style.filter = existingFilters+"alpha(opacity="+this._opacity+")";
+ }
+
+ this._updateOpacity = this._updateOpacityMSIE;
+
+ } else {
+
+ this._updateOpacity = this._updateVisibility;
+ }
+
+ this._updateOpacity();
+ }
+
+ // Initiates a fade out
+ Fadomatic.prototype.fadeOut = function () {
+ this._isFadeOut = true;
+ this._beginFade();
+ }
+
+ // Initiates a fade in
+ Fadomatic.prototype.fadeIn = function () {
+ this._isFadeOut = false;
+ this._beginFade();
+ }
+
+ // Makes the element completely opaque, stops any fade in progress
+ Fadomatic.prototype.show = function () {
+ this.haltFade();
+ this._opacity = this._maxOpacity;
+ this._updateOpacity();
+ }
+
+ // Makes the element completely transparent, stops any fade in progress
+ Fadomatic.prototype.hide = function () {
+ this.haltFade();
+ this._opacity = 0;
+ this._updateOpacity();
+ }
+
+ // Halts any fade in progress
+ Fadomatic.prototype.haltFade = function () {
+
+ clearInterval(this._intervalId);
+ }
+
+ // Resumes a fade where it was halted
+ Fadomatic.prototype.resumeFade = function () {
+
+ this._beginFade();
+ }
+
+ // Pseudo-private members
+
+ Fadomatic.prototype._beginFade = function () {
+
+ this.haltFade();
+ var objref = this;
+ this._intervalId = setInterval(function() { objref._tickFade(); },Fadomatic.INTERVAL_MILLIS);
+ }
+
+ Fadomatic.prototype._tickFade = function () {
+
+ if (this._isFadeOut) {
+ this._opacity -= this._rate;
+ if (this._opacity < this._minOpacity) {
+ this._opacity = this._minOpacity;
+ this.haltFade();
+ }
+ } else {
+ this._opacity += this._rate;
+ if (this._opacity > this._maxOpacity ) {
+ this._opacity = this._maxOpacity;
+ this.haltFade();
+ }
+ }
+
+ this._updateOpacity();
+ }
+
+ Fadomatic.prototype._updateVisibility = function () {
+
+ if (this._opacity > 0) {
+ this._element.style.visibility = 'visible';
+ } else {
+ this._element.style.visibility = 'hidden';
+ }
+ }
+
+ Fadomatic.prototype._updateOpacityW3c = function () {
+
+ this._element.style.opacity = this._opacity/100;
+ this._updateVisibility();
+ }
+
+ Fadomatic.prototype._updateOpacityMSIE = function () {
+
+ this._element.filters.alpha.opacity = this._opacity;
+ this._updateVisibility();
+ }
+
+ Fadomatic.prototype._updateOpacity = null;
+
+
+ // Override CoalescedHTML methods
+ function outputHTML() {
+ var insert = document.getElementById("insert");
+ if(!!insert && coalescedHTML.isConsecutive) {
+ insert.parentNode.replaceChild(coalescedHTML.fragment, insert);
+ } else {
+ if(insert)
+ insert.parentNode.removeChild(insert);
+ // insert the documentFragment into the live DOM
+ try {
+ var fader = new Fadomatic(coalescedHTML.fragment, 9, 0, 0, 95);
+ } catch(e) {
+ trace(e);
+ }
+ fader.fadeIn();
+ }
+
+ alignChat(coalescedHTML.shouldScroll);
+
+ // reset state to empty/non-coalescing
+ coalescedHTML.shouldScroll = undefined;
+ coalescedHTML.isConsecutive = undefined;
+ coalescedHTML.isCoalescing = false;
+ coalescedHTML.coalesceRounds = 0;
+ }
+
+ CoalescedHTML.prototype.coalesce = function() {
+ window.clearTimeout(this.timeoutID);
+ this.timeoutID = window.setTimeout(outputHTML, 25);
+ this.isCoalescing = true;
+ this.coalesceRounds += 1;
+ if(400 < self.coalesceRounds)
+ this.cancel();
+ }
+
+ //Do this on load
+ function initEvents() {
+ if(document.getElementById("heading") == null){
+ document.getElementById("bodyNode").style.marginTop = "5px";
+ }
+ if(isDebug == false) {
+ document.getElementById("debug").style.display = "none";
+ }
+ }
+
+ function adiumOnLoad() {
+ initEvents();
+ alignChat(true);
+ coalescedHTML = new CoalescedHTML();
+ }
+
+</script>
\ No newline at end of file
diff -r 594253d97431 -r 6beac534df5b Resources/Message Styles/renkoo.AdiumMessageStyle/Contents/Resources/Template.html
--- a/Resources/Message Styles/renkoo.AdiumMessageStyle/Contents/Resources/Template.html Fri Oct 30 12:11:03 2009 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,436 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
- <base href="%@">
-
- <script type="text/javascript">
- //<![CDATA[
-
- isDebug = false;
-
- // Fade interval in milliseconds
- // Make this larger if you experience performance issues
- Fadomatic.INTERVAL_MILLIS = 50;
-
- // Creates a fader
- // element - The element to fade
- // speed - The speed to fade at, from 0.0 to 100.0
- // initialOpacity (optional, default 100) - element's starting opacity, 0 to 100
- // minOpacity (optional, default 0) - element's minimum opacity, 0 to 100
- // maxOpacity (optional, default 0) - element's minimum opacity, 0 to 100
- function Fadomatic (element, rate, initialOpacity, minOpacity, maxOpacity) {
- this._element = element;
- this._intervalId = null;
- this._rate = rate;
- this._isFadeOut = true;
-
- // Set initial opacity and bounds
- // NB use 99 instead of 100 to avoid flicker at start of fade
- this._minOpacity = 0;
- this._maxOpacity = 99;
- this._opacity = 99;
-
- if (typeof minOpacity != 'undefined') {
- if (minOpacity < 0) {
- this._minOpacity = 0;
- } else if (minOpacity > 99) {
- this._minOpacity = 99;
- } else {
- this._minOpacity = minOpacity;
- }
- }
-
- if (typeof maxOpacity != 'undefined') {
- if (maxOpacity < 0) {
- this._maxOpacity = 0;
- } else if (maxOpacity > 99) {
- this._maxOpacity = 99;
- } else {
- this._maxOpacity = maxOpacity;
- }
-
- if (this._maxOpacity < this._minOpacity) {
- this._maxOpacity = this._minOpacity;
- }
- }
-
- if (typeof initialOpacity != 'undefined') {
- if (initialOpacity > this._maxOpacity) {
- this._opacity = this._maxOpacity;
- } else if (initialOpacity < this._minOpacity) {
- this._opacity = this._minOpacity;
- } else {
- this._opacity = initialOpacity;
- }
- }
-
- // See if we're using W3C opacity, MSIE filter, or just
- // toggling visiblity
- if(typeof element.style.opacity != 'undefined') {
-
- this._updateOpacity = this._updateOpacityW3c;
-
- } else if(typeof element.style.filter != 'undefined') {
-
- // If there's not an alpha filter on the element already,
- // add one
- if (element.style.filter.indexOf("alpha") == -1) {
-
- // Attempt to preserve existing filters
- var existingFilters="";
- if (element.style.filter) {
- existingFilters = element.style.filter+" ";
- }
- element.style.filter = existingFilters+"alpha(opacity="+this._opacity+")";
- }
-
- this._updateOpacity = this._updateOpacityMSIE;
-
- } else {
-
- this._updateOpacity = this._updateVisibility;
- }
-
- this._updateOpacity();
- }
-
- // Initiates a fade out
- Fadomatic.prototype.fadeOut = function () {
- this._isFadeOut = true;
- this._beginFade();
- }
-
- // Initiates a fade in
- Fadomatic.prototype.fadeIn = function () {
- this._isFadeOut = false;
- this._beginFade();
- }
-
- // Makes the element completely opaque, stops any fade in progress
- Fadomatic.prototype.show = function () {
- this.haltFade();
- this._opacity = this._maxOpacity;
- this._updateOpacity();
- }
-
- // Makes the element completely transparent, stops any fade in progress
- Fadomatic.prototype.hide = function () {
- this.haltFade();
- this._opacity = 0;
- this._updateOpacity();
- }
-
- // Halts any fade in progress
- Fadomatic.prototype.haltFade = function () {
-
- clearInterval(this._intervalId);
- }
-
- // Resumes a fade where it was halted
- Fadomatic.prototype.resumeFade = function () {
-
- this._beginFade();
- }
-
- // Pseudo-private members
-
- Fadomatic.prototype._beginFade = function () {
-
- this.haltFade();
- var objref = this;
- this._intervalId = setInterval(function() { objref._tickFade(); },Fadomatic.INTERVAL_MILLIS);
- }
-
- Fadomatic.prototype._tickFade = function () {
-
- if (this._isFadeOut) {
- this._opacity -= this._rate;
- if (this._opacity < this._minOpacity) {
- this._opacity = this._minOpacity;
- this.haltFade();
- }
- } else {
- this._opacity += this._rate;
- if (this._opacity > this._maxOpacity ) {
- this._opacity = this._maxOpacity;
- this.haltFade();
- }
- }
-
- this._updateOpacity();
- }
-
- Fadomatic.prototype._updateVisibility = function () {
-
- if (this._opacity > 0) {
- this._element.style.visibility = 'visible';
- } else {
- this._element.style.visibility = 'hidden';
- }
- }
-
- Fadomatic.prototype._updateOpacityW3c = function () {
-
- this._element.style.opacity = this._opacity/100;
- this._updateVisibility();
- }
-
- Fadomatic.prototype._updateOpacityMSIE = function () {
-
- this._element.filters.alpha.opacity = this._opacity;
- this._updateVisibility();
- }
-
- Fadomatic.prototype._updateOpacity = null;
-
-
-
- //Do this on load
- function initEvents() {
- if(document.getElementById("heading") == null){
- document.getElementById("bodyNode").style.marginTop = "5px";
- }
-
- if(isDebug == false) {
- document.getElementById("debug").style.display = "none";
- }
-
-
- alignChat(true);
- }
-
- //Debugging function
- function trace(msg) {
- var node = document.createElement("div");
- var debugCon = document.getElementById("debug");
- node.innerHTML = msg;
- debugCon.appendChild(node);
- }
-
-
- //Appending new content to the message view
- function appendMessage(html) {
- var shouldScroll = nearBottom();
-
- //Remove any existing insertion point
- var insert = document.getElementById("insert");
-
- if(insert) insert.parentNode.removeChild(insert);
-
- //Append the new message to the bottom of our chat block
- var chat = document.getElementById("Chat");
- var range = document.createRange();
- range.selectNode(chat);
- var documentFragment = range.createContextualFragment(html);
- var myFrag = chat.appendChild(documentFragment);
- var frag = document.getElementById("insert").parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
-
- try {
- var fader = new Fadomatic(frag, 9, 0, 0, 95);
- } catch(e) {
- trace(e);
- }
- fader.fadeIn();
-
- alignChat(true);
- }
-
- function appendMessageNoScroll(html) {
- //Remove any existing insertion point
- var insert = document.getElementById("insert");
-
- if(insert) insert.parentNode.removeChild(insert);
-
- //Append the new message to the bottom of our chat block
- var chat = document.getElementById("Chat");
- var range = document.createRange();
- range.selectNode(chat);
- var documentFragment = range.createContextualFragment(html);
- var myFrag = chat.appendChild(documentFragment);
- var frag = document.getElementById("insert").parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
-
- try {
- var fader = new Fadomatic(frag, 9, 0, 0, 95);
- } catch(e) {
- trace(e);
- }
- fader.fadeIn();
- }
-
- function appendNextMessage(html){
- var shouldScroll = nearBottom();
-
- //Locate the insertion point
- var insert = document.getElementById("insert");
-
- //make new node
- range = document.createRange();
- range.selectNode(insert.parentNode);
- newNode = range.createContextualFragment(html);
-
- //swap
- var pointer = insert.parentNode;
- insert.parentNode.replaceChild(newNode,insert);
- var els = pointer.getElementsByTagName("div");
-
- alignChat(true);
- }
-
- function appendNextMessageNoScroll(html){
- //Locate the insertion point
- var insert = document.getElementById("insert");
-
- //make new node
- range = document.createRange();
- range.selectNode(insert.parentNode);
- newNode = range.createContextualFragment(html);
-
- //swap
- var pointer = insert.parentNode;
- insert.parentNode.replaceChild(newNode,insert);
- var els = pointer.getElementsByTagName("div");
- }
-
- function replaceLastMessage(html){
- shouldScroll = nearBottom();
-
- //Retrieve the current insertion point, then remove it
- //This requires that there have been an insertion point... is there a better way to retrieve the last element? -evands
- var insert = document.getElementById("insert");
- var parentNode = insert.parentNode;
- var lastMessage = insert.previousSibling;
- parentNode.removeChild(insert);
- parentNode.removeChild(lastMessage);
-
- //Now append the message itself
- var range = document.createRange();
- var chat = document.getElementById("Chat");
- range.selectNode(chat);
- documentFragment = range.createContextualFragment(html);
- chat.appendChild(documentFragment);
-
- alignChat(shouldScroll);
- }
-
- //Auto-scroll to bottom. Use nearBottom to determine if a scrollToBottom is desired.
- function nearBottom() {
- return ( document.body.scrollTop >= ( document.body.offsetHeight - ( window.innerHeight * 1.2 ) ) );
- }
-
- var intervall_scroll;
- function scrollToBottom() {
- //document.body.scrollTop = (document.body.scrollHeight-window.innerHeight);
- //return;
- if( intervall_scroll ) clearInterval( intervall_scroll );
- intervall_scroll = setInterval( function() {
- var target_scroll = (document.body.scrollHeight-window.innerHeight);
- var scrolldiff = target_scroll - document.body.scrollTop;
- if ( document.body.scrollTop != target_scroll ) {
- var saved_scroll = document.body.scrollTop;
- document.body.scrollTop += scrolldiff / 5 + ( scrolldiff >= 0 ? (scrolldiff != 0 ) : -1 );
- } else {
- saved_scroll = -1;
- clearInterval( intervall_scroll );
- }
- } , 10 );
- return;
- }
-
-
- //Dynamically exchange the active stylesheet
- function setStylesheet( id, url ) {
- var code = "<style id=\"" + id + "\" type=\"text/css\" media=\"screen,print\">";
- if( url.length ) code += "@import url( \"" + url + "\" );";
- code += "</style>";
- var range = document.createRange();
- var head = document.getElementsByTagName( "head" ).item(0);
- range.selectNode( head );
- documentFragment = range.createContextualFragment( code );
- head.removeChild( document.getElementById( id ) );
- head.appendChild( documentFragment );
- }
-
- //Swap an image with its alt-tag text on click
- document.onclick = imageCheck;
- function imageCheck() {
- var node = event.target;
- if(node.tagName.toLowerCase() == 'img' && !client.zoomImage(node) && node.alt && (node.className != "avatar")) {
- var a = document.createElement('a');
- a.setAttribute('onclick', 'imageSwap(this)');
- a.setAttribute('src', node.getAttribute('src'));
- a.className = node.className;
- var text = document.createTextNode(node.alt);
- a.appendChild(text);
- node.parentNode.replaceChild(a, node);
- }
- }
- function imageSwap(node) {
- var shouldScroll = nearBottom();
-
- //Swap the image/text
- var img = document.createElement('img');
- img.setAttribute('src', node.getAttribute('src'));
- img.setAttribute('alt', node.firstChild.nodeValue);
- img.className = node.className;
- node.parentNode.replaceChild(img, node);
-
- alignChat(shouldScroll);
- }
-
- //Align our chat to the bottom of the window. If true is passed, view will also be scrolled down
- function alignChat(shouldScroll) {
-
- var windowHeight = window.innerHeight;
-
- if(windowHeight > 0) {
- var contentElement = document.getElementById('Chat');
- var contentHeight = contentElement.offsetHeight;
- if (windowHeight - contentHeight > 0) {
- contentElement.style.position = 'relative';
- contentElement.style.top = '0px';
- } else {
- contentElement.style.position = 'static';
- }
- }
-
- if(shouldScroll) scrollToBottom();
- }
-
- function windowDidResize() {
- alignChat(true/*nearBottom()*/); //nearBottom buggy with inavtive tabs
- }
-
- window.onresize = windowDidResize;
- //]]>
- </script>
-
- <style type="text/css">
- .actionMessageUserName { display:none; }
- .actionMessageBody:before { content:"*"; }
- .actionMessageBody:after { content:"*"; }
- *{ word-wrap:break-word; }
- img.scaledToFitImage { height:auto; width:100%; }
- </style>
-
- <!-- This style is shared by all variants. !-->
- <style id="baseStyle" type="text/css" media="screen,print">
- %@
- </style>
-
- <!-- Although we call this mainStyle for legacy reasons, it's actually the variant style !-->
- <style id="mainStyle" type="text/css" media="screen,print">
- @import url( "%@" );
- </style>
-
-
-</head>
-<body style="==bodyBackground==" id="bodyNode" onload="initEvents()">
-%@
-<div id="Chat">
-</div>
-%@
-<div id="debug"></div>
-</body>
-</html>
\ No newline at end of file
More information about the commits
mailing list