Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Handle dynamic document titles #19

Closed
wants to merge 2 commits into from

3 participants

Peter Baumgartner Tom Moor Simon Gaeremynck
Peter Baumgartner
ipmb commented March 08, 2012

Adds fallbackMethod option for dynamic document titles

  • static is the traditional behavior based on the original document title
  • dynamic uses a regex to replace the title in the event the original document title changed since the script loaded
added some commits March 08, 2012
Peter Baumgartner Adds `fallbackMethod` option for dynamic document titles
* `static` is the traditional behavior based on the original document title
* `dynamic` uses a regex to replace the title in the event the original document title changed since the script loaded
ed2c2de
Peter Baumgartner declare `titleSplit` variable eb26115
Tom Moor
Owner

Hey, can you think of any reason why you would want to use the static method? I'm reluctant to add extra options unless really necessary :-)

Peter Baumgartner
ipmb commented March 12, 2012

This isn't fool-proof. If you started with a page title in the form (20) Some Text it would overwrite the (20) part. You'd need to be smarter about handling the fallback for these instances, probably maintaining some internal state.

Simon Gaeremynck

Any progress on this? I'm willing to help out...

Simon Gaeremynck

FWIW, I don't see any reason why their needs to be a static v dynamic distinction at all.
The fact that updateTitle doesn't take the current title into account feels like a bug and can be fixed without worrying about backwards compatibility (IMHO) in a major release.

I'd be willing to submit a new PR for that logic if there is interest ..

Tom Moor
Owner

Agree with @simong, whilst this would be a great improvement - there shouldn't need to be a distinction and the lib should just be able to handle this situation.

Simon Gaeremynck simong referenced this pull request from a commit in simong/tinycon January 21, 2014
Simon Gaeremynck #19 - bugfix for handling dynamic document titles 9cc67d6
Simon Gaeremynck

I've submitted a PR at #57 which addresses the issue directly.

Tom Moor
Owner

Closed by @simong in 9cc67d6, this implementation was preferred as it requires no extra work on behalf of the user.

Tom Moor tommoor closed this February 09, 2014
Christopher Blum tiff referenced this pull request from a commit in protonet/tinycon January 21, 2014
Simon Gaeremynck #19 - bugfix for handling dynamic document titles fa2a323
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 2 unique commits by 1 author.

Mar 08, 2012
Peter Baumgartner Adds `fallbackMethod` option for dynamic document titles
* `static` is the traditional behavior based on the original document title
* `dynamic` uses a regex to replace the title in the event the original document title changed since the script loaded
ed2c2de
Peter Baumgartner declare `titleSplit` variable eb26115
This page is out of date. Refresh to see the latest.

Showing 1 changed file with 60 additions and 56 deletions. Show diff stats Hide diff stats

  1. 116  tinycon.js
116  tinycon.js
@@ -7,11 +7,12 @@
7 7
 */
8 8
 
9 9
 (function(){
10  
-	
  10
+
11 11
 	var Tinycon = {};
12 12
 	var currentFavicon = null;
13 13
 	var originalFavicon = null;
14 14
 	var originalTitle = document.title;
  15
+	var titleRegEx = new RegExp('^\\(\\d+\\) ');
15 16
 	var faviconImage = null;
16 17
 	var canvas = null;
17 18
 	var options = {};
@@ -21,9 +22,10 @@
21 22
 		font: '10px arial',
22 23
 		colour: '#ffffff',
23 24
 		background: '#F03D25',
24  
-		fallback: true
  25
+		fallback: true,
  26
+		fallbackMethod: 'static'
25 27
 	};
26  
-	
  28
+
27 29
 	var ua = (function () {
28 30
 		var agent = navigator.userAgent.toLowerCase();
29 31
 		// New function has access to 'agent' via closure
@@ -38,35 +40,35 @@
38 40
 		safari: ua('safari') && !ua('chrome'),
39 41
 		mozilla: ua('mozilla') && !ua('chrome') && !ua('safari')
40 42
 	};
41  
-	
  43
+
42 44
 	// private
43 45
 	var getFaviconTag = function(){
44  
-		
  46
+
45 47
 		var links = document.getElementsByTagName('link');
46  
-		
  48
+
47 49
 		for(var i=0, len=links.length; i < len; i++) {
48 50
 			if ((links[i].getAttribute('rel') || '').match(/\bicon\b/)) {
49 51
 				return links[i];
50 52
 			}
51 53
 		}
52  
-		
  54
+
53 55
 		return false;
54 56
 	};
55  
-	
  57
+
56 58
 	var removeFaviconTag = function(){
57  
-	
  59
+
58 60
 		var links = document.getElementsByTagName('link');
59 61
 		var head = document.getElementsByTagName('head')[0];
60  
-		
  62
+
61 63
 		for(var i=0, len=links.length; i < len; i++) {
62 64
 			if (links[i].getAttribute('rel') === 'icon') {
63 65
 				head.removeChild(links[i]);
64 66
 			}
65 67
 		}
66 68
 	};
67  
-	
  69
+
68 70
 	var getCurrentFavicon = function(){
69  
-		
  71
+
70 72
 		if (!originalFavicon || !currentFavicon) {
71 73
 			var tag = getFaviconTag();
72 74
 			originalFavicon = currentFavicon = tag ? tag.getAttribute('href') : '/favicon.ico';
@@ -74,76 +76,78 @@
74 76
 
75 77
 		return currentFavicon;
76 78
 	};
77  
-	
  79
+
78 80
 	var getCanvas = function (){
79  
-		
  81
+
80 82
 		if (!canvas) {
81 83
 			canvas = document.createElement("canvas");
82 84
 			canvas.width = 16;
83 85
 			canvas.height = 16;
84 86
 		}
85  
-		
  87
+
86 88
 		return canvas;
87 89
 	};
88  
-	
  90
+
89 91
 	var setFaviconTag = function(url){
90 92
 		removeFaviconTag();
91  
-		
  93
+
92 94
 		var link = document.createElement('link');
93 95
 		link.type = 'image/x-icon';
94 96
 		link.rel = 'icon';
95 97
 		link.href = url;
96 98
 		document.getElementsByTagName('head')[0].appendChild(link);
97 99
 	};
98  
-	
  100
+
99 101
 	var log = function(message){
100 102
 		if (window.console) window.console.log(message);
101 103
 	};
102  
-	
  104
+
103 105
 	var drawFavicon = function(num, colour) {
104 106
 
105 107
 		// fallback to updating the browser title if unsupported
106 108
 		if (!getCanvas().getContext || browser.safari || options.fallback === 'force') {
107 109
 			return updateTitle(num);
108 110
 		}
109  
-		
  111
+
110 112
 		var context = getCanvas().getContext("2d");
111 113
 		var colour = colour || '#000000';
112 114
 		var num = num || 0;
113  
-		
  115
+
114 116
 		faviconImage = new Image();
115 117
 		faviconImage.crossOrigin = 'anonymous';
116 118
 		faviconImage.onload = function() {
117  
-			
118  
-			// clear canvas  
  119
+
  120
+			// clear canvas
119 121
 			context.clearRect(0, 0, 16, 16);
120 122
 
121 123
 			// draw original favicon
122 124
 			context.drawImage(faviconImage, 0, 0, faviconImage.width, faviconImage.height, 0, 0, 16, 16);
123  
-			
  125
+
124 126
 			// draw bubble over the top
125 127
 			if (num > 0) drawBubble(context, num, colour);
126  
-			
  128
+
127 129
 			// refresh tag in page
128 130
 			refreshFavicon();
129 131
 		};
130  
-		
  132
+
131 133
 		faviconImage.src = getCurrentFavicon();
132 134
 	};
133  
-	
  135
+
134 136
 	var updateTitle = function(num) {
135  
-		
136  
-		if (options.fallback) {
137  
-			if (num > 0) {
138  
-				document.title = '('+num+') ' + originalTitle;
139  
-			} else {
140  
-				document.title = originalTitle;
141  
-			}
142  
-		}
  137
+            if (options.fallback) {
  138
+                var titleSplit,
  139
+                    numText = num > 0 ? '('+num+') ' : '';
  140
+                if (options.fallbackMethod === 'static') {
  141
+                    document.title = numText + originalTitle;
  142
+                } else if (options.fallbackMethod === 'dynamic') {
  143
+                    titleSplit = document.title.split(titleRegEx);
  144
+                    document.title = numText + titleSplit.slice(-1);
  145
+                }
  146
+            }
143 147
 	};
144  
-	
  148
+
145 149
 	var drawBubble = function(context, num, colour) {
146  
-		
  150
+
147 151
 		// bubble needs to be larger for double digits
148 152
 		var len = (num+"").length-1;
149 153
 		var width = options.width + (6*len);
@@ -155,75 +159,75 @@
155 159
 		context.fillStyle = options.background;
156 160
 		context.strokeStyle = options.background;
157 161
 		context.lineWidth = 1;
158  
-		
  162
+
159 163
 		// bubble
160 164
 		context.fillRect(w,h,width-1,options.height);
161  
-		
  165
+
162 166
 		// rounded left
163 167
 		context.beginPath();
164 168
 		context.moveTo(w-0.5,h+1);
165 169
 		context.lineTo(w-0.5,15);
166 170
 		context.stroke();
167  
-		
  171
+
168 172
 		// rounded right
169 173
 		context.beginPath();
170 174
 		context.moveTo(15.5,h+1);
171 175
 		context.lineTo(15.5,15);
172 176
 		context.stroke();
173  
-		
  177
+
174 178
 		// bottom shadow
175 179
 		context.beginPath();
176 180
 		context.strokeStyle = "rgba(0,0,0,0.3)";
177 181
 		context.moveTo(w,16);
178 182
 		context.lineTo(15,16);
179 183
 		context.stroke();
180  
-		
  184
+
181 185
 		// number
182 186
 		context.fillStyle = options.colour;
183 187
 		context.textAlign = "right";
184 188
 		context.textBaseline = "top";
185  
-		
  189
+
186 190
 		// unfortunately webkit/mozilla are a pixel different in text positioning
187  
-		context.fillText(num, 15, browser.mozilla ? 7 : 6);  
  191
+		context.fillText(num, 15, browser.mozilla ? 7 : 6);
188 192
 	};
189  
-	
  193
+
190 194
 	var refreshFavicon = function(){
191 195
 		// check support
192 196
 		if (!getCanvas().getContext) return;
193  
-		
  197
+
194 198
 		setFaviconTag(getCanvas().toDataURL());
195 199
 	};
196  
-	
197  
-	
  200
+
  201
+
198 202
 	// public
199 203
 	Tinycon.setOptions = function(custom){
200 204
 		options = {};
201  
-		
  205
+
202 206
 		for(var i in defaults){
203 207
 			options[i] = custom[i] ? custom[i] : defaults[i];
204 208
 		}
205 209
 		return this;
206 210
 	};
207  
-	
  211
+
208 212
 	Tinycon.setImage = function(url){
209 213
 		currentFavicon = url;
210 214
 		refreshFavicon();
211 215
 		return this;
212 216
 	};
213  
-	
  217
+
214 218
 	Tinycon.setBubble = function(num, colour){
215  
-		
  219
+
216 220
 		// validate
217 221
 		if(isNaN(num)) return log('Bubble must be a number');
218  
-		
  222
+
219 223
 		drawFavicon(num, colour);
220 224
 		return this;
221 225
 	};
222  
-	
  226
+
223 227
 	Tinycon.reset = function(){
224 228
 		Tinycon.setImage(originalFavicon);
225 229
 	};
226  
-	
  230
+
227 231
 	Tinycon.setOptions(defaults);
228 232
 	window.Tinycon = Tinycon;
229  
-})();
  233
+})();
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.