Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/images/wikiEditor/dialogs/button_disabled.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/images/wikiEditor/dialogs/button_down.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/images/wikiEditor/dialogs/button_off.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/images/wikiEditor/dialogs/button_over.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/ClickTracking/ClickTracking.i18n.php |
— | — | @@ -539,6 +539,7 @@ |
540 | 540 | |
541 | 541 | /** Basque (Euskara) |
542 | 542 | * @author An13sa |
| 543 | + * @author Unai Fdz. de Betoño |
543 | 544 | */ |
544 | 545 | $messages['eu'] = array( |
545 | 546 | 'ct-event-name' => 'Ekintzaren izena', |
— | — | @@ -553,6 +554,7 @@ |
554 | 555 | 'ct-intermediate' => 'Maila ertainekoa', |
555 | 556 | 'ct-expert' => 'Aditua', |
556 | 557 | 'ct-anon-users' => 'Lankide anonimoak', |
| 558 | + 'ct-user-contribs' => 'Lankidearen ekarpen guztiak', |
557 | 559 | 'ct-and' => 'eta', |
558 | 560 | 'ct-update-table' => 'Taula eguneratu', |
559 | 561 | ); |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/css/combined.css |
— | — | @@ -137,7 +137,6 @@ |
138 | 138 | position: relative; |
139 | 139 | clear: both; |
140 | 140 | width: 100%; |
141 | | - line-height: 1em; |
142 | 141 | background-color: #f3f3f3; |
143 | 142 | border: solid silver 1px; |
144 | 143 | } |
— | — | @@ -222,40 +221,38 @@ |
223 | 222 | .wikiEditor-ui-tabs div.current a:hover { |
224 | 223 | text-decoration: none; |
225 | 224 | } |
| 225 | + |
| 226 | +.wikiEditor-view-wikitext { |
| 227 | + line-height: 1em; |
| 228 | +} |
226 | 229 | /* wikiEditor dialogs module */ |
227 | 230 | |
228 | | -.ui-widget table { |
| 231 | +.wikiEditor-toolbar-dialog table { |
229 | 232 | margin-top: 0.75em; |
230 | 233 | } |
231 | | -.ui-widget table td { |
| 234 | +.wikiEditor-toolbar-dialog table td { |
232 | 235 | padding: 0.5em; |
233 | 236 | height: 3em; |
234 | 237 | overflow: visible; |
235 | 238 | } |
236 | | - |
237 | | - |
238 | | - |
239 | 239 | /* Put suggestions (default z-index 99) on top of dialogs (z-index 1002) */ |
240 | 240 | div.suggestions { |
241 | 241 | z-index: 1099; |
242 | 242 | } |
243 | | - |
244 | | -.ui-dialog .ui-dialog-titlebar-close:hover { |
| 243 | +.wikiEditor-toolbar-dialog .ui-dialog-titlebar-close:hover { |
245 | 244 | text-decoration: none; |
246 | 245 | } |
247 | | -.ui-dialog-content .status-invalid input { |
| 246 | +.wikiEditor-toolbar-dialog .ui-dialog-content .status-invalid input { |
248 | 247 | border: 2px solid red; |
249 | 248 | padding: 2px 1px; |
250 | 249 | } |
251 | | - |
252 | | - |
253 | | -.ui-dialog .ui-dialog-titlebar { |
| 250 | +.wikiEditor-toolbar-dialog .ui-dialog-titlebar { |
254 | 251 | padding: 0.9em 1.4em 0.6em !important; |
255 | 252 | } |
256 | | -.ui-widget table td { |
| 253 | +.wikiEditor-toolbar-dialog table td { |
257 | 254 | padding: 0 !important; |
258 | 255 | } |
259 | | -.ui-dialog .ui-dialog-buttonpane button { |
| 256 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button { |
260 | 257 | -moz-border-radius: 4px; |
261 | 258 | -webkit-border-radius: 4px; |
262 | 259 | padding: 0.2em 0.6em 0.15em !important; |
— | — | @@ -263,54 +260,55 @@ |
264 | 261 | border: 1px solid #a6a6a6 !important; |
265 | 262 | background: #f2f2f2 url( ../images/wikiEditor/dialogs/button_off.png ) repeat-x scroll 50% 100% !important; |
266 | 263 | } |
267 | | -.ui-dialog .ui-dialog-buttonpane button:hover { |
268 | | - background: #ebf2f9 url( ../images/wikiEditor/dialogs/button_over.png ) repeat-x scroll 50% 100% !important; |
| 264 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button:hover { |
| 265 | + border-color: #6e7273; |
| 266 | + background: #e1e1e1 url( ../images/wikiEditor/dialogs/button_over.png ) repeat-x scroll 50% 100% !important; |
269 | 267 | } |
270 | | -.ui-dialog .ui-dialog-buttonpane button:active, |
271 | | -.ui-dialog .ui-dialog-buttonpane button:focus { |
272 | | - |
| 268 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button:active, |
| 269 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button:focus { |
| 270 | + border-color: #707271; |
273 | 271 | background: #bfbfbf url( ../images/wikiEditor/dialogs/button_down.png ) repeat-x scroll 50% 100% !important; |
274 | 272 | } |
275 | | -.ui-dialog .ui-dialog-buttonpane button.disabled { |
| 273 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button.disabled { |
276 | 274 | color: #7f7f7f; |
277 | 275 | border-color: #cccccc; |
278 | 276 | background: #f2f2f2 url( ../images/wikiEditor/dialogs/button_disabled.png ) repeat-x scroll 50% 100% !important; |
279 | 277 | } |
280 | 278 | /* Disables the annoying dashed border Firefox puts on active buttons */ |
281 | | -.ui-dialog .ui-dialog-buttonpane button::-moz-focus-inner { |
| 279 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button::-moz-focus-inner { |
282 | 280 | border: 0; |
283 | 281 | } |
284 | | -.ui-widget-header { |
| 282 | +.wikiEditor-toolbar-dialog .ui-widget-header { |
285 | 283 | background: #f0f0f0 url( ../images/wikiEditor/dialogs/titlebar_fade.png ) repeat-x scroll 50% 100% !important; |
286 | 284 | } |
287 | 285 | /* FIXME: Should just update the icon sprite if we're keeping this X */ |
288 | | -.ui-icon-closethick { |
| 286 | +.wikiEditor-toolbar-dialog .ui-icon-closethick { |
289 | 287 | background: url( ../images/wikiEditor/dialogs/close_x.png ) no-repeat 50% 50% !important; |
290 | 288 | } |
291 | | -.ui-dialog .ui-dialog-buttonpane { |
| 289 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane { |
292 | 290 | margin-top: 0 !important; |
293 | 291 | padding:0.3em 1.4em 0.5em 1.4em !important; |
294 | 292 | } |
295 | 293 | |
296 | | -.ui-dialog-content fieldset{ |
| 294 | +.wikiEditor-toolbar-dialog .ui-dialog-content fieldset{ |
297 | 295 | border: none !important; |
298 | 296 | margin: 0 !important; |
299 | 297 | padding: 0 !important; |
300 | 298 | } |
301 | | -.ui-widget-header { |
| 299 | +.wikiEditor-toolbar-dialog .ui-widget-header { |
302 | 300 | border-bottom:1px solid #6bc8f3 !important; |
303 | 301 | } |
304 | | -.ui-dialog-content input[type=text] { |
| 302 | +.wikiEditor-toolbar-dialog .ui-dialog-content input[type=text] { |
305 | 303 | -moz-box-sizing: border-box; |
306 | 304 | -ms-box-sizing: border-box; |
307 | 305 | -webkit-box-sizing: border-box; |
308 | 306 | -khtml-box-sizing: border-box; |
309 | 307 | } |
310 | | -.ui-dialog-content input[type="radio"], |
311 | | -.ui-dialog-content input[type="checkbox"] { |
| 308 | +.wikiEditor-toolbar-dialog .ui-dialog-content input[type="radio"], |
| 309 | +.wikiEditor-toolbar-dialog .ui-dialog-content input[type="checkbox"] { |
312 | 310 | margin-left: 0; |
313 | 311 | } |
314 | | -body.ltr .ui-dialog .ui-dialog-titlebar-close { |
| 312 | +body.ltr .wikiEditor-toolbar-dialog .ui-dialog-titlebar-close { |
315 | 313 | right: 0.9em; |
316 | 314 | } |
317 | 315 | .wikieditor-toolbar-field-wrapper { |
— | — | @@ -340,21 +338,21 @@ |
341 | 339 | body.rtl #wikieditor-toolbar-table-dialog .wikieditor-toolbar-table-preview-wrapper { |
342 | 340 | float: left; |
343 | 341 | } |
344 | | -body.rtl .ui-widget .wikieditor-toolbar-table-preview-wrapper table { |
| 342 | +body.rtl .wikiEditor-toolbar-dialog .wikieditor-toolbar-table-preview-wrapper table { |
345 | 343 | margin-left: 1em; |
346 | 344 | margin-right: 0; |
347 | 345 | } |
348 | 346 | .wikieditor-toolbar-table-preview-content * { |
349 | 347 | cursor: default; |
350 | 348 | } |
351 | | -.ui-widget .wikieditor-toolbar-table-preview-wrapper table { |
| 349 | +.wikiEditor-toolbar-dialog .wikieditor-toolbar-table-preview-wrapper table { |
352 | 350 | width: 100% !important; |
353 | 351 | } |
354 | | -.ui-widget .wikieditor-toolbar-table-preview-content table td { |
| 352 | +.wikiEditor-toolbar-dialog .wikieditor-toolbar-table-preview-content table td { |
355 | 353 | padding: 10px 4px !important; |
356 | 354 | height: auto !important; |
357 | 355 | } |
358 | | -.ui-widget .wikieditor-toolbar-table-preview-content table th { |
| 356 | +.wikiEditor-toolbar-dialog .wikieditor-toolbar-table-preview-content table th { |
359 | 357 | padding: 7px 3px !important; |
360 | 358 | } |
361 | 359 | .wikieditor-toolbar-table-dimension-fields .wikieditor-toolbar-field-wrapper { |
— | — | @@ -367,7 +365,7 @@ |
368 | 366 | margin-right: 0px; |
369 | 367 | margin-left: 20px; |
370 | 368 | } |
371 | | -.ui-dialog .ui-dialog-content { |
| 369 | +.wikiEditor-toolbar-dialog .ui-dialog-content { |
372 | 370 | padding: 30px 20px 0 !important; |
373 | 371 | } |
374 | 372 | .wikieditor-toolbar-dialog-wrapper { |
— | — | @@ -376,15 +374,15 @@ |
377 | 375 | /* REPLACE Dialog */ |
378 | 376 | |
379 | 377 | /* RTL Changes */ |
380 | | -body.rtl .ui-dialog .ui-dialog-buttonpane button { |
| 378 | +body.rtl .wikiEditor-toolbar-dialog .ui-dialog-buttonpane button { |
381 | 379 | float: left; |
382 | 380 | margin: 0.5em 0.4em 0.5em 0 !important; |
383 | 381 | } |
384 | | -body.rtl .ui-dialog .ui-dialog-titlebar-close { |
| 382 | +body.rtl .wikiEditor-toolbar-dialog .ui-dialog-titlebar-close { |
385 | 383 | left: 0.9em; |
386 | 384 | right: auto; |
387 | 385 | } |
388 | | -body.rtl .ui-dialog .ui-dialog-title { |
| 386 | +body.rtl .wikiEditor-toolbar-dialog .ui-dialog-title { |
389 | 387 | float:right; |
390 | 388 | } |
391 | 389 | /* Self Clearing Floats */ |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/css/combined.min.css |
— | — | @@ -129,7 +129,6 @@ |
130 | 130 | position:relative; |
131 | 131 | clear:both; |
132 | 132 | width:100%; |
133 | | -line-height:1em; |
134 | 133 | background-color:#f3f3f3; |
135 | 134 | border:solid silver 1px; |
136 | 135 | } |
— | — | @@ -213,10 +212,13 @@ |
214 | 213 | .wikiEditor-ui-tabs div.current a:hover{ |
215 | 214 | text-decoration:none; |
216 | 215 | } |
217 | | -.ui-widget table{ |
| 216 | +.wikiEditor-view-wikitext{ |
| 217 | +line-height:1em; |
| 218 | +} |
| 219 | +.wikiEditor-toolbar-dialog table{ |
218 | 220 | margin-top:0.75em; |
219 | 221 | } |
220 | | -.ui-widget table td{ |
| 222 | +.wikiEditor-toolbar-dialog table td{ |
221 | 223 | padding:0.5em; |
222 | 224 | height:3em; |
223 | 225 | overflow:visible; |
— | — | @@ -224,20 +226,20 @@ |
225 | 227 | div.suggestions{ |
226 | 228 | z-index:1099; |
227 | 229 | } |
228 | | -.ui-dialog .ui-dialog-titlebar-close:hover{ |
| 230 | +.wikiEditor-toolbar-dialog .ui-dialog-titlebar-close:hover{ |
229 | 231 | text-decoration:none; |
230 | 232 | } |
231 | | -.ui-dialog-content .status-invalid input{ |
| 233 | +.wikiEditor-toolbar-dialog .ui-dialog-content .status-invalid input{ |
232 | 234 | border:2px solid red; |
233 | 235 | padding:2px 1px; |
234 | 236 | } |
235 | | -.ui-dialog .ui-dialog-titlebar{ |
| 237 | +.wikiEditor-toolbar-dialog .ui-dialog-titlebar{ |
236 | 238 | padding:0.9em 1.4em 0.6em !important; |
237 | 239 | } |
238 | | -.ui-widget table td{ |
| 240 | +.wikiEditor-toolbar-dialog table td{ |
239 | 241 | padding:0 !important; |
240 | 242 | } |
241 | | -.ui-dialog .ui-dialog-buttonpane button{ |
| 243 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button{ |
242 | 244 | -moz-border-radius:4px; |
243 | 245 | -webkit-border-radius:4px; |
244 | 246 | padding:0.2em 0.6em 0.15em !important; |
— | — | @@ -245,50 +247,52 @@ |
246 | 248 | border:1px solid #a6a6a6 !important; |
247 | 249 | background:#f2f2f2 url( ../images/wikiEditor/dialogs/button_off.png ) repeat-x scroll 50% 100% !important; |
248 | 250 | } |
249 | | -.ui-dialog .ui-dialog-buttonpane button:hover{ |
250 | | -background:#ebf2f9 url( ../images/wikiEditor/dialogs/button_over.png ) repeat-x scroll 50% 100% !important; |
| 251 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button:hover{ |
| 252 | +border-color:#6e7273; |
| 253 | +background:#e1e1e1 url( ../images/wikiEditor/dialogs/button_over.png ) repeat-x scroll 50% 100% !important; |
251 | 254 | } |
252 | | -.ui-dialog .ui-dialog-buttonpane button:active, |
253 | | -.ui-dialog .ui-dialog-buttonpane button:focus{ |
| 255 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button:active, |
| 256 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button:focus{ |
| 257 | +border-color:#707271; |
254 | 258 | background:#bfbfbf url( ../images/wikiEditor/dialogs/button_down.png ) repeat-x scroll 50% 100% !important; |
255 | 259 | } |
256 | | -.ui-dialog .ui-dialog-buttonpane button.disabled{ |
| 260 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button.disabled{ |
257 | 261 | color:#7f7f7f; |
258 | 262 | border-color:#cccccc; |
259 | 263 | background:#f2f2f2 url( ../images/wikiEditor/dialogs/button_disabled.png ) repeat-x scroll 50% 100% !important; |
260 | 264 | } |
261 | | -.ui-dialog .ui-dialog-buttonpane button::-moz-focus-inner{ |
| 265 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button::-moz-focus-inner{ |
262 | 266 | border:0; |
263 | 267 | } |
264 | | -.ui-widget-header{ |
| 268 | +.wikiEditor-toolbar-dialog .ui-widget-header{ |
265 | 269 | background:#f0f0f0 url( ../images/wikiEditor/dialogs/titlebar_fade.png ) repeat-x scroll 50% 100% !important; |
266 | 270 | } |
267 | | -.ui-icon-closethick{ |
| 271 | +.wikiEditor-toolbar-dialog .ui-icon-closethick{ |
268 | 272 | background:url( ../images/wikiEditor/dialogs/close_x.png ) no-repeat 50% 50% !important; |
269 | 273 | } |
270 | | -.ui-dialog .ui-dialog-buttonpane{ |
| 274 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane{ |
271 | 275 | margin-top:0 !important; |
272 | 276 | padding:0.3em 1.4em 0.5em 1.4em !important; |
273 | 277 | } |
274 | | -.ui-dialog-content fieldset{ |
| 278 | +.wikiEditor-toolbar-dialog .ui-dialog-content fieldset{ |
275 | 279 | border:none !important; |
276 | 280 | margin:0 !important; |
277 | 281 | padding:0 !important; |
278 | 282 | } |
279 | | -.ui-widget-header{ |
| 283 | +.wikiEditor-toolbar-dialog .ui-widget-header{ |
280 | 284 | border-bottom:1px solid #6bc8f3 !important; |
281 | 285 | } |
282 | | -.ui-dialog-content input[type=text]{ |
| 286 | +.wikiEditor-toolbar-dialog .ui-dialog-content input[type=text]{ |
283 | 287 | -moz-box-sizing:border-box; |
284 | 288 | -ms-box-sizing:border-box; |
285 | 289 | -webkit-box-sizing:border-box; |
286 | 290 | -khtml-box-sizing:border-box; |
287 | 291 | } |
288 | | -.ui-dialog-content input[type="radio"], |
289 | | -.ui-dialog-content input[type="checkbox"]{ |
| 292 | +.wikiEditor-toolbar-dialog .ui-dialog-content input[type="radio"], |
| 293 | +.wikiEditor-toolbar-dialog .ui-dialog-content input[type="checkbox"]{ |
290 | 294 | margin-left:0; |
291 | 295 | } |
292 | | -body.ltr .ui-dialog .ui-dialog-titlebar-close{ |
| 296 | +body.ltr .wikiEditor-toolbar-dialog .ui-dialog-titlebar-close{ |
293 | 297 | right:0.9em; |
294 | 298 | } |
295 | 299 | .wikieditor-toolbar-field-wrapper{ |
— | — | @@ -316,21 +320,21 @@ |
317 | 321 | body.rtl #wikieditor-toolbar-table-dialog .wikieditor-toolbar-table-preview-wrapper{ |
318 | 322 | float:left; |
319 | 323 | } |
320 | | -body.rtl .ui-widget .wikieditor-toolbar-table-preview-wrapper table{ |
| 324 | +body.rtl .wikiEditor-toolbar-dialog .wikieditor-toolbar-table-preview-wrapper table{ |
321 | 325 | margin-left:1em; |
322 | 326 | margin-right:0; |
323 | 327 | } |
324 | 328 | .wikieditor-toolbar-table-preview-content *{ |
325 | 329 | cursor:default; |
326 | 330 | } |
327 | | -.ui-widget .wikieditor-toolbar-table-preview-wrapper table{ |
| 331 | +.wikiEditor-toolbar-dialog .wikieditor-toolbar-table-preview-wrapper table{ |
328 | 332 | width:100% !important; |
329 | 333 | } |
330 | | -.ui-widget .wikieditor-toolbar-table-preview-content table td{ |
| 334 | +.wikiEditor-toolbar-dialog .wikieditor-toolbar-table-preview-content table td{ |
331 | 335 | padding:10px 4px !important; |
332 | 336 | height:auto !important; |
333 | 337 | } |
334 | | -.ui-widget .wikieditor-toolbar-table-preview-content table th{ |
| 338 | +.wikiEditor-toolbar-dialog .wikieditor-toolbar-table-preview-content table th{ |
335 | 339 | padding:7px 3px !important; |
336 | 340 | } |
337 | 341 | .wikieditor-toolbar-table-dimension-fields .wikieditor-toolbar-field-wrapper{ |
— | — | @@ -343,21 +347,21 @@ |
344 | 348 | margin-right:0px; |
345 | 349 | margin-left:20px; |
346 | 350 | } |
347 | | -.ui-dialog .ui-dialog-content{ |
| 351 | +.wikiEditor-toolbar-dialog .ui-dialog-content{ |
348 | 352 | padding:30px 20px 0 !important; |
349 | 353 | } |
350 | 354 | .wikieditor-toolbar-dialog-wrapper{ |
351 | 355 | width:100%; |
352 | 356 | } |
353 | | -body.rtl .ui-dialog .ui-dialog-buttonpane button{ |
| 357 | +body.rtl .wikiEditor-toolbar-dialog .ui-dialog-buttonpane button{ |
354 | 358 | float:left; |
355 | 359 | margin:0.5em 0.4em 0.5em 0 !important; |
356 | 360 | } |
357 | | -body.rtl .ui-dialog .ui-dialog-titlebar-close{ |
| 361 | +body.rtl .wikiEditor-toolbar-dialog .ui-dialog-titlebar-close{ |
358 | 362 | left:0.9em; |
359 | 363 | right:auto; |
360 | 364 | } |
361 | | -body.rtl .ui-dialog .ui-dialog-title{ |
| 365 | +body.rtl .wikiEditor-toolbar-dialog .ui-dialog-title{ |
362 | 366 | float:right; |
363 | 367 | } |
364 | 368 | .wikieditor-toolbar-table-dimension-fields:after, |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/css/wikiEditor.css |
— | — | @@ -24,7 +24,6 @@ |
25 | 25 | position: relative; |
26 | 26 | clear: both; |
27 | 27 | width: 100%; |
28 | | - line-height: 1em; |
29 | 28 | background-color: #f3f3f3; |
30 | 29 | border: solid silver 1px; |
31 | 30 | } |
— | — | @@ -109,3 +108,7 @@ |
110 | 109 | .wikiEditor-ui-tabs div.current a:hover { |
111 | 110 | text-decoration: none; |
112 | 111 | } |
| 112 | + |
| 113 | +.wikiEditor-view-wikitext { |
| 114 | + line-height: 1em; |
| 115 | +} |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/css/wikiEditor.dialogs.css |
— | — | @@ -1,37 +1,31 @@ |
2 | 2 | /* wikiEditor dialogs module */ |
3 | 3 | |
4 | | -.ui-widget table { |
| 4 | +.wikiEditor-toolbar-dialog table { |
5 | 5 | margin-top: 0.75em; |
6 | 6 | } |
7 | | -.ui-widget table td { |
| 7 | +.wikiEditor-toolbar-dialog table td { |
8 | 8 | padding: 0.5em; |
9 | 9 | height: 3em; |
10 | 10 | overflow: visible; |
11 | 11 | } |
12 | | - |
13 | | - |
14 | | - |
15 | 12 | /* Put suggestions (default z-index 99) on top of dialogs (z-index 1002) */ |
16 | 13 | div.suggestions { |
17 | 14 | z-index: 1099; |
18 | 15 | } |
19 | | - |
20 | | -.ui-dialog .ui-dialog-titlebar-close:hover { |
| 16 | +.wikiEditor-toolbar-dialog .ui-dialog-titlebar-close:hover { |
21 | 17 | text-decoration: none; |
22 | 18 | } |
23 | | -.ui-dialog-content .status-invalid input { |
| 19 | +.wikiEditor-toolbar-dialog .ui-dialog-content .status-invalid input { |
24 | 20 | border: 2px solid red; |
25 | 21 | padding: 2px 1px; |
26 | 22 | } |
27 | | - |
28 | | - |
29 | | -.ui-dialog .ui-dialog-titlebar { |
| 23 | +.wikiEditor-toolbar-dialog .ui-dialog-titlebar { |
30 | 24 | padding: 0.9em 1.4em 0.6em !important; |
31 | 25 | } |
32 | | -.ui-widget table td { |
| 26 | +.wikiEditor-toolbar-dialog table td { |
33 | 27 | padding: 0 !important; |
34 | 28 | } |
35 | | -.ui-dialog .ui-dialog-buttonpane button { |
| 29 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button { |
36 | 30 | -moz-border-radius: 4px; |
37 | 31 | -webkit-border-radius: 4px; |
38 | 32 | padding: 0.2em 0.6em 0.15em !important; |
— | — | @@ -39,54 +33,55 @@ |
40 | 34 | border: 1px solid #a6a6a6 !important; |
41 | 35 | background: #f2f2f2 url( ../images/wikiEditor/dialogs/button_off.png ) repeat-x scroll 50% 100% !important; |
42 | 36 | } |
43 | | -.ui-dialog .ui-dialog-buttonpane button:hover { |
44 | | - background: #ebf2f9 url( ../images/wikiEditor/dialogs/button_over.png ) repeat-x scroll 50% 100% !important; |
| 37 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button:hover { |
| 38 | + border-color: #6e7273; |
| 39 | + background: #e1e1e1 url( ../images/wikiEditor/dialogs/button_over.png ) repeat-x scroll 50% 100% !important; |
45 | 40 | } |
46 | | -.ui-dialog .ui-dialog-buttonpane button:active, |
47 | | -.ui-dialog .ui-dialog-buttonpane button:focus { |
48 | | - |
| 41 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button:active, |
| 42 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button:focus { |
| 43 | + border-color: #707271; |
49 | 44 | background: #bfbfbf url( ../images/wikiEditor/dialogs/button_down.png ) repeat-x scroll 50% 100% !important; |
50 | 45 | } |
51 | | -.ui-dialog .ui-dialog-buttonpane button.disabled { |
| 46 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button.disabled { |
52 | 47 | color: #7f7f7f; |
53 | 48 | border-color: #cccccc; |
54 | 49 | background: #f2f2f2 url( ../images/wikiEditor/dialogs/button_disabled.png ) repeat-x scroll 50% 100% !important; |
55 | 50 | } |
56 | 51 | /* Disables the annoying dashed border Firefox puts on active buttons */ |
57 | | -.ui-dialog .ui-dialog-buttonpane button::-moz-focus-inner { |
| 52 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane button::-moz-focus-inner { |
58 | 53 | border: 0; |
59 | 54 | } |
60 | | -.ui-widget-header { |
| 55 | +.wikiEditor-toolbar-dialog .ui-widget-header { |
61 | 56 | background: #f0f0f0 url( ../images/wikiEditor/dialogs/titlebar_fade.png ) repeat-x scroll 50% 100% !important; |
62 | 57 | } |
63 | 58 | /* FIXME: Should just update the icon sprite if we're keeping this X */ |
64 | | -.ui-icon-closethick { |
| 59 | +.wikiEditor-toolbar-dialog .ui-icon-closethick { |
65 | 60 | background: url( ../images/wikiEditor/dialogs/close_x.png ) no-repeat 50% 50% !important; |
66 | 61 | } |
67 | | -.ui-dialog .ui-dialog-buttonpane { |
| 62 | +.wikiEditor-toolbar-dialog .ui-dialog-buttonpane { |
68 | 63 | margin-top: 0 !important; |
69 | 64 | padding:0.3em 1.4em 0.5em 1.4em !important; |
70 | 65 | } |
71 | 66 | |
72 | | -.ui-dialog-content fieldset{ |
| 67 | +.wikiEditor-toolbar-dialog .ui-dialog-content fieldset{ |
73 | 68 | border: none !important; |
74 | 69 | margin: 0 !important; |
75 | 70 | padding: 0 !important; |
76 | 71 | } |
77 | | -.ui-widget-header { |
| 72 | +.wikiEditor-toolbar-dialog .ui-widget-header { |
78 | 73 | border-bottom:1px solid #6bc8f3 !important; |
79 | 74 | } |
80 | | -.ui-dialog-content input[type=text] { |
| 75 | +.wikiEditor-toolbar-dialog .ui-dialog-content input[type=text] { |
81 | 76 | -moz-box-sizing: border-box; |
82 | 77 | -ms-box-sizing: border-box; |
83 | 78 | -webkit-box-sizing: border-box; |
84 | 79 | -khtml-box-sizing: border-box; |
85 | 80 | } |
86 | | -.ui-dialog-content input[type="radio"], |
87 | | -.ui-dialog-content input[type="checkbox"] { |
| 81 | +.wikiEditor-toolbar-dialog .ui-dialog-content input[type="radio"], |
| 82 | +.wikiEditor-toolbar-dialog .ui-dialog-content input[type="checkbox"] { |
88 | 83 | margin-left: 0; |
89 | 84 | } |
90 | | -body.ltr .ui-dialog .ui-dialog-titlebar-close { |
| 85 | +body.ltr .wikiEditor-toolbar-dialog .ui-dialog-titlebar-close { |
91 | 86 | right: 0.9em; |
92 | 87 | } |
93 | 88 | .wikieditor-toolbar-field-wrapper { |
— | — | @@ -116,21 +111,21 @@ |
117 | 112 | body.rtl #wikieditor-toolbar-table-dialog .wikieditor-toolbar-table-preview-wrapper { |
118 | 113 | float: left; |
119 | 114 | } |
120 | | -body.rtl .ui-widget .wikieditor-toolbar-table-preview-wrapper table { |
| 115 | +body.rtl .wikiEditor-toolbar-dialog .wikieditor-toolbar-table-preview-wrapper table { |
121 | 116 | margin-left: 1em; |
122 | 117 | margin-right: 0; |
123 | 118 | } |
124 | 119 | .wikieditor-toolbar-table-preview-content * { |
125 | 120 | cursor: default; |
126 | 121 | } |
127 | | -.ui-widget .wikieditor-toolbar-table-preview-wrapper table { |
| 122 | +.wikiEditor-toolbar-dialog .wikieditor-toolbar-table-preview-wrapper table { |
128 | 123 | width: 100% !important; |
129 | 124 | } |
130 | | -.ui-widget .wikieditor-toolbar-table-preview-content table td { |
| 125 | +.wikiEditor-toolbar-dialog .wikieditor-toolbar-table-preview-content table td { |
131 | 126 | padding: 10px 4px !important; |
132 | 127 | height: auto !important; |
133 | 128 | } |
134 | | -.ui-widget .wikieditor-toolbar-table-preview-content table th { |
| 129 | +.wikiEditor-toolbar-dialog .wikieditor-toolbar-table-preview-content table th { |
135 | 130 | padding: 7px 3px !important; |
136 | 131 | } |
137 | 132 | .wikieditor-toolbar-table-dimension-fields .wikieditor-toolbar-field-wrapper { |
— | — | @@ -143,7 +138,7 @@ |
144 | 139 | margin-right: 0px; |
145 | 140 | margin-left: 20px; |
146 | 141 | } |
147 | | -.ui-dialog .ui-dialog-content { |
| 142 | +.wikiEditor-toolbar-dialog .ui-dialog-content { |
148 | 143 | padding: 30px 20px 0 !important; |
149 | 144 | } |
150 | 145 | .wikieditor-toolbar-dialog-wrapper { |
— | — | @@ -152,15 +147,15 @@ |
153 | 148 | /* REPLACE Dialog */ |
154 | 149 | |
155 | 150 | /* RTL Changes */ |
156 | | -body.rtl .ui-dialog .ui-dialog-buttonpane button { |
| 151 | +body.rtl .wikiEditor-toolbar-dialog .ui-dialog-buttonpane button { |
157 | 152 | float: left; |
158 | 153 | margin: 0.5em 0.4em 0.5em 0 !important; |
159 | 154 | } |
160 | | -body.rtl .ui-dialog .ui-dialog-titlebar-close { |
| 155 | +body.rtl .wikiEditor-toolbar-dialog .ui-dialog-titlebar-close { |
161 | 156 | left: 0.9em; |
162 | 157 | right: auto; |
163 | 158 | } |
164 | | -body.rtl .ui-dialog .ui-dialog-title { |
| 159 | +body.rtl .wikiEditor-toolbar-dialog .ui-dialog-title { |
165 | 160 | float:right; |
166 | 161 | } |
167 | 162 | /* Self Clearing Floats */ |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/WikiEditor/WikiEditor.hooks.php |
— | — | @@ -16,14 +16,14 @@ |
17 | 17 | array( 'src' => 'Modules/Preview/Preview.js', 'version' => 6 ), |
18 | 18 | array( 'src' => 'Modules/Publish/Publish.js', 'version' => 6 ), |
19 | 19 | array( 'src' => 'Modules/Toc/Toc.js', 'version' => 7 ), |
20 | | - array( 'src' => 'Modules/Toolbar/Toolbar.js', 'version' => 37 ), |
| 20 | + array( 'src' => 'Modules/Toolbar/Toolbar.js', 'version' => 40 ), |
21 | 21 | array( 'src' => 'Modules/TemplateEditor/TemplateEditor.js', 'version' => 4 ), |
22 | 22 | ), |
23 | 23 | 'combined' => array( |
24 | | - array( 'src' => 'WikiEditor.combined.js', 'version' => 39 ), |
| 24 | + array( 'src' => 'WikiEditor.combined.js', 'version' => 42 ), |
25 | 25 | ), |
26 | 26 | 'minified' => array( |
27 | | - array( 'src' => 'WikiEditor.combined.min.js', 'version' => 39 ), |
| 27 | + array( 'src' => 'WikiEditor.combined.min.js', 'version' => 42 ), |
28 | 28 | ), |
29 | 29 | ); |
30 | 30 | static $messages = array( |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/WikiEditor/WikiEditor.combined.js |
— | — | @@ -929,26 +929,27 @@ |
930 | 930 | } |
931 | 931 | return s.match( arguments.callee.regex ); |
932 | 932 | } |
| 933 | + // Updates the status indicator above the target link |
| 934 | + function updateWidget( status ) { |
| 935 | + $j( '#wikieditor-toolbar-link-int-target-status' ).children().hide(); |
| 936 | + $j( '#wikieditor-toolbar-link-int-target' ).parent() |
| 937 | + .removeClass( 'status-invalid status-external status-notexists status-exists status-loading' ); |
| 938 | + if ( status ) { |
| 939 | + $j( '#wikieditor-toolbar-link-int-target-status-' + status ).show(); |
| 940 | + $j( '#wikieditor-toolbar-link-int-target' ).parent().addClass( 'status-' + status ); |
| 941 | + } |
| 942 | + if ( status == 'invalid' ) { |
| 943 | + $j( '.ui-dialog:visible .ui-dialog-buttonpane button:first' ) |
| 944 | + .attr( 'disabled', true ) |
| 945 | + .addClass( 'disabled' ); |
| 946 | + } else { |
| 947 | + $j( '.ui-dialog:visible .ui-dialog-buttonpane button:first' ) |
| 948 | + .removeAttr('disabled') |
| 949 | + .removeClass('disabled'); |
| 950 | + } |
| 951 | + } |
933 | 952 | // Updates the UI to show if the page title being inputed by the user exists or not |
934 | 953 | function updateExistence() { |
935 | | - function updateWidget( status ) { |
936 | | - $j( '#wikieditor-toolbar-link-int-target-status' ).children().hide(); |
937 | | - $j( '#wikieditor-toolbar-link-int-target' ).parent() |
938 | | - .removeClass( 'status-invalid status-external status-notexists status-exists status-loading' ); |
939 | | - if ( status ) { |
940 | | - $j( '#wikieditor-toolbar-link-int-target-status-' + status ).show(); |
941 | | - $j( '#wikieditor-toolbar-link-int-target' ).parent().addClass( 'status-' + status ); |
942 | | - } |
943 | | - if ( status == 'invalid' ) { |
944 | | - $j( '.ui-dialog:visible .ui-dialog-buttonpane button:first' ) |
945 | | - .attr( 'disabled', true ) |
946 | | - .addClass( 'disabled' ); |
947 | | - } else { |
948 | | - $j( '.ui-dialog:visible .ui-dialog-buttonpane button:first' ) |
949 | | - .removeAttr('disabled') |
950 | | - .removeClass('disabled'); |
951 | | - } |
952 | | - } |
953 | 954 | // Abort previous request |
954 | 955 | var request = $j( '#wikieditor-toolbar-link-int-target-status' ).data( 'request' ); |
955 | 956 | if ( request ) { |
— | — | @@ -1008,6 +1009,12 @@ |
1009 | 1010 | } ) |
1010 | 1011 | ); |
1011 | 1012 | } |
| 1013 | + $j( '#wikieditor-toolbar-link-type-int, #wikieditor-toolbar-link-type-ext' ).click( function() { |
| 1014 | + if( $j( '#wikieditor-toolbar-link-type-ext' ).is( ':checked' ) ) |
| 1015 | + updateWidget( 'external' ); |
| 1016 | + if( $j( '#wikieditor-toolbar-link-type-int' ).is( ':checked' ) ) |
| 1017 | + updateExistence(); |
| 1018 | + }); |
1012 | 1019 | // Set labels of tabs based on rel values |
1013 | 1020 | var u = mw.usability; |
1014 | 1021 | $j(this).find( '[rel]' ).each( function() { |
— | — | @@ -1173,16 +1180,20 @@ |
1174 | 1181 | }, |
1175 | 1182 | dialog: { |
1176 | 1183 | width: 500, |
| 1184 | + dialogClass: 'wikiEditor-toolbar-dialog', |
1177 | 1185 | buttons: { |
1178 | 1186 | 'wikieditor-toolbar-tool-link-insert': function() { |
1179 | 1187 | function escapeInternalText( s ) { |
| 1188 | + // FIXME: Should this escape [[ too? Seems to work without that |
1180 | 1189 | return s.replace( /(]{2,})/g, '<nowiki>$1</nowiki>' ); |
1181 | 1190 | } |
1182 | 1191 | function escapeExternalTarget( s ) { |
1183 | 1192 | return s.replace( / /g, '%20' ) |
| 1193 | + .replace( /\[/g, '%5B' ) |
1184 | 1194 | .replace( /]/g, '%5D' ); |
1185 | 1195 | } |
1186 | 1196 | function escapeExternalText( s ) { |
| 1197 | + // FIXME: Should this escape [ too? Seems to work without that |
1187 | 1198 | return s.replace( /(]+)/g, '<nowiki>$1</nowiki>' ); |
1188 | 1199 | } |
1189 | 1200 | var insertText = ''; |
— | — | @@ -1450,6 +1461,7 @@ |
1451 | 1462 | }, |
1452 | 1463 | dialog: { |
1453 | 1464 | resizable: false, |
| 1465 | + dialogClass: 'wikiEditor-toolbar-dialog', |
1454 | 1466 | width: 590, |
1455 | 1467 | buttons: { |
1456 | 1468 | 'wikieditor-toolbar-tool-table-insert': function() { |
— | — | @@ -1682,6 +1694,7 @@ |
1683 | 1695 | }, |
1684 | 1696 | dialog: { |
1685 | 1697 | width: 500, |
| 1698 | + dialogClass: 'wikiEditor-toolbar-dialog', |
1686 | 1699 | buttons: { |
1687 | 1700 | 'wikieditor-toolbar-tool-replace-button-findnext': function( e ) { |
1688 | 1701 | $j(this).closest( '.ui-dialog' ).data( 'dialogaction', e.target ); |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/WikiEditor/WikiEditor.combined.min.js |
— | — | @@ -27,9 +27,9 @@ |
28 | 28 | </div>\ |
29 | 29 | </fieldset>',init:function(){function isExternalLink(s){if(typeof arguments.callee.regex=='undefined'){arguments.callee.regex=new RegExp("(^("+wgUrlProtocols+"))|(^www\\.)|([^.]\\.[a-z]{2,}($|\\/))",'i');} |
30 | 30 | return s.match(arguments.callee.regex);} |
31 | | -function updateExistence(){function updateWidget(status){$j('#wikieditor-toolbar-link-int-target-status').children().hide();$j('#wikieditor-toolbar-link-int-target').parent().removeClass('status-invalid status-external status-notexists status-exists status-loading');if(status){$j('#wikieditor-toolbar-link-int-target-status-'+status).show();$j('#wikieditor-toolbar-link-int-target').parent().addClass('status-'+status);} |
| 31 | +function updateWidget(status){$j('#wikieditor-toolbar-link-int-target-status').children().hide();$j('#wikieditor-toolbar-link-int-target').parent().removeClass('status-invalid status-external status-notexists status-exists status-loading');if(status){$j('#wikieditor-toolbar-link-int-target-status-'+status).show();$j('#wikieditor-toolbar-link-int-target').parent().addClass('status-'+status);} |
32 | 32 | if(status=='invalid'){$j('.ui-dialog:visible .ui-dialog-buttonpane button:first').attr('disabled',true).addClass('disabled');}else{$j('.ui-dialog:visible .ui-dialog-buttonpane button:first').removeAttr('disabled').removeClass('disabled');}} |
33 | | -var request=$j('#wikieditor-toolbar-link-int-target-status').data('request');if(request){request.abort();} |
| 33 | +function updateExistence(){var request=$j('#wikieditor-toolbar-link-int-target-status').data('request');if(request){request.abort();} |
34 | 34 | var target=$j('#wikieditor-toolbar-link-int-target').val();var cache=$j('#wikieditor-toolbar-link-int-target-status').data('existencecache');if(cache[target]){updateWidget(cache[target]);return;} |
35 | 35 | if(target==''){updateWidget(false);return;} |
36 | 36 | if(isExternalLink(target)){updateWidget('external');return;} |
— | — | @@ -38,7 +38,9 @@ |
39 | 39 | status='notexists';else if(typeof page.invalid!='undefined') |
40 | 40 | status='invalid';} |
41 | 41 | cache[target]=status;updateWidget(status);}}));} |
42 | | -var u=mw.usability;$j(this).find('[rel]').each(function(){$j(this).text(u.getMsg($j(this).attr('rel')));});$j('#wikieditor-toolbar-link-int-target').data('tooltip',u.getMsg('wikieditor-toolbar-tool-link-int-target-tooltip'));$j('#wikieditor-toolbar-link-int-text').data('tooltip',u.getMsg('wikieditor-toolbar-tool-link-int-text-tooltip'));$j('#wikieditor-toolbar-link-int-target, #wikieditor-toolbar-link-int-text').each(function(){var tooltip=u.getMsg($j(this).attr('id')+'-tooltip');if($j(this).val()=='') |
| 42 | +$j('#wikieditor-toolbar-link-type-int, #wikieditor-toolbar-link-type-ext').click(function(){if($j('#wikieditor-toolbar-link-type-ext').is(':checked')) |
| 43 | +updateWidget('external');if($j('#wikieditor-toolbar-link-type-int').is(':checked')) |
| 44 | +updateExistence();});var u=mw.usability;$j(this).find('[rel]').each(function(){$j(this).text(u.getMsg($j(this).attr('rel')));});$j('#wikieditor-toolbar-link-int-target').data('tooltip',u.getMsg('wikieditor-toolbar-tool-link-int-target-tooltip'));$j('#wikieditor-toolbar-link-int-text').data('tooltip',u.getMsg('wikieditor-toolbar-tool-link-int-text-tooltip'));$j('#wikieditor-toolbar-link-int-target, #wikieditor-toolbar-link-int-text').each(function(){var tooltip=u.getMsg($j(this).attr('id')+'-tooltip');if($j(this).val()=='') |
43 | 45 | $j(this).val($j(this).data('tooltip')).addClass('wikieditor-toolbar-dialog-hint');}).focus(function(){$j(this).removeClass('wikieditor-toolbar-dialog-hint');if($j(this).val()==$j(this).data('tooltip')) |
44 | 46 | $j(this).val('');}).bind('blur change',function(){if($j(this).val()=='') |
45 | 47 | $j(this).val($j(this).data('tooltip')).addClass('wikieditor-toolbar-dialog-hint');else |
— | — | @@ -51,8 +53,8 @@ |
52 | 54 | updateExistence();});$j('#wikieditor-toolbar-link-int-target').data('suggcache',{}).suggestions({fetch:function(query){var that=this;var title=$j(this).val();if(isExternalLink(title)||title.indexOf('|')!=-1||title==''){$j(this).suggestions('suggestions',[]);return;} |
53 | 55 | var cache=$j(this).data('suggcache');if(typeof cache[title]!='undefined'){$j(this).suggestions('suggestions',cache[title]);return;} |
54 | 56 | var request=$j.ajax({url:wgScriptPath+'/api.php',data:{'action':'opensearch','search':title,'namespace':0,'suggest':'','format':'json'},dataType:'json',success:function(data){cache[title]=data[1];$j(that).suggestions('suggestions',data[1]);}});$j(this).data('request',request);},cancel:function(){var request=$j(this).data('request');if(request) |
55 | | -request.abort();}});},dialog:{width:500,buttons:{'wikieditor-toolbar-tool-link-insert':function(){function escapeInternalText(s){return s.replace(/(]{2,})/g,'<nowiki>$1</nowiki>');} |
56 | | -function escapeExternalTarget(s){return s.replace(/ /g,'%20').replace(/]/g,'%5D');} |
| 57 | +request.abort();}});},dialog:{width:500,dialogClass:'wikiEditor-toolbar-dialog',buttons:{'wikieditor-toolbar-tool-link-insert':function(){function escapeInternalText(s){return s.replace(/(]{2,})/g,'<nowiki>$1</nowiki>');} |
| 58 | +function escapeExternalTarget(s){return s.replace(/ /g,'%20').replace(/\[/g,'%5B').replace(/]/g,'%5D');} |
57 | 59 | function escapeExternalText(s){return s.replace(/(]+)/g,'<nowiki>$1</nowiki>');} |
58 | 60 | var insertText='';var whitespace=$j('#wikieditor-toolbar-link-dialog').data('whitespace');var target=$j('#wikieditor-toolbar-link-int-target').val();var text=$j('#wikieditor-toolbar-link-int-text').val();var u=mw.usability;if(target==''){alert(u.getMsg('wikieditor-toolbar-tool-link-empty'));return;} |
59 | 61 | if($j.trim(text)==''){text='';} |
— | — | @@ -129,7 +131,7 @@ |
130 | 132 | </div>\ |
131 | 133 | </div></div>',init:function(){$j(this).find('[rel]').each(function(){$j(this).text(mw.usability.getMsg($j(this).attr('rel')));});$j('#wikieditor-toolbar-table-dimensions-rows').val(4);$j('#wikieditor-toolbar-table-dimensions-columns').val(3);$j('#wikieditor-toolbar-table-wikitable').click(function(){$j('.wikieditor-toolbar-table-preview').toggleClass('wikitable');});$j('#wikieditor-toolbar-table-preview').clone().attr('id','wikieditor-toolbar-table-preview2').addClass('sortable').insertAfter($j('#wikieditor-toolbar-table-preview')).hide();if(typeof ts_makeSortable=='function') |
132 | 134 | ts_makeSortable($j('#wikieditor-toolbar-table-preview2').get(0));$j('#wikieditor-toolbar-table-sortable').click(function(){$j('#wikieditor-toolbar-table-preview').hide().attr('id','wikieditor-toolbar-table-preview3');$j('#wikieditor-toolbar-table-preview2').attr('id','wikieditor-toolbar-table-preview').show();$j('#wikieditor-toolbar-table-preview3').attr('id','wikieditor-toolbar-table-preview2');});$j('#wikieditor-toolbar-table-dimensions-header').click(function(){var headerHTML=$j('.wikieditor-toolbar-table-preview-header').html();var hiddenHTML=$j('.wikieditor-toolbar-table-preview-hidden').html();$j('.wikieditor-toolbar-table-preview-header').html(hiddenHTML);$j('.wikieditor-toolbar-table-preview-hidden').html(headerHTML);if(typeof ts_makeSortable=='function') |
133 | | -ts_makeSortable($j('#wikieditor-toolbar-table-preview, #wikieditor-toolbar-table-preview2').filter('.sortable').get(0));});},dialog:{resizable:false,width:590,buttons:{'wikieditor-toolbar-tool-table-insert':function(){var rowsVal=$j('#wikieditor-toolbar-table-dimensions-rows').val();var colsVal=$j('#wikieditor-toolbar-table-dimensions-columns').val();var rows=parseInt(rowsVal,10);var cols=parseInt(colsVal,10);var header=Math.min(1,$j('#wikieditor-toolbar-table-dimensions-header:checked').size());var u=mw.usability;if(isNaN(rows)||isNaN(cols)||rows!=rowsVal||cols!=colsVal){alert(u.getMsg('wikieditor-toolbar-tool-table-invalidnumber'));return;} |
| 135 | +ts_makeSortable($j('#wikieditor-toolbar-table-preview, #wikieditor-toolbar-table-preview2').filter('.sortable').get(0));});},dialog:{resizable:false,dialogClass:'wikiEditor-toolbar-dialog',width:590,buttons:{'wikieditor-toolbar-tool-table-insert':function(){var rowsVal=$j('#wikieditor-toolbar-table-dimensions-rows').val();var colsVal=$j('#wikieditor-toolbar-table-dimensions-columns').val();var rows=parseInt(rowsVal,10);var cols=parseInt(colsVal,10);var header=Math.min(1,$j('#wikieditor-toolbar-table-dimensions-header:checked').size());var u=mw.usability;if(isNaN(rows)||isNaN(cols)||rows!=rowsVal||cols!=colsVal){alert(u.getMsg('wikieditor-toolbar-tool-table-invalidnumber'));return;} |
134 | 136 | if(rows+header==0||cols==0){alert(u.getMsg('wikieditor-toolbar-tool-table-zero'));return;} |
135 | 137 | if(rows*cols>1000){alert(u.getMsg('wikieditor-toolbar-tool-table-toomany',1000));return;} |
136 | 138 | var headerText=u.getMsg('wikieditor-toolbar-tool-table-example-header');var normalText=u.getMsg('wikieditor-toolbar-tool-table-example');var table="";for(var r=0;r<rows+header;r++){table+="|-\n";for(var c=0;c<cols;c++){var isHeader=(r+1==header);var delim=isHeader?'!':'|';if(c>0){delim+=delim;} |
— | — | @@ -174,6 +176,6 @@ |
175 | 177 | if(!match){$j('#wikieditor-toolbar-replace-nomatch').show();}else if(mode=='replaceAll'){var index;for(var i=0;i<match.length;i++){index=s.indexOf(match[i]);if(index==-1){break;} |
176 | 178 | s=s.substr(index+match[i].length);var start=index+offset;var end=start+match[i].length;var newEnd=start+replaceStr.length;$textarea.textSelection('setSelection',{'start':start,'end':end}).textSelection('encapsulateSelection',{'peri':replaceStr,'replace':true}).textSelection('setSelection',{'start':start,'end':newEnd});offset=newEnd;} |
177 | 179 | $j('#wikieditor-toolbar-replace-success').text(u.getMsg('wikieditor-toolbar-tool-replace-success',match.length)).show();$j(this).data('offset',0);}else{var start=match.index+offset;var end=start+match[0].length;var newEnd=start+replaceStr.length;$textarea.textSelection('setSelection',{'start':start,'end':end});if(mode=='replace'){$textarea.textSelection('encapsulateSelection',{'peri':replaceStr,'replace':true}).textSelection('setSelection',{'start':start,'end':newEnd});} |
178 | | -$textarea.textSelection('scrollToCaretPosition');$j(this).data('offset',mode=='replace'?newEnd:end);}});},dialog:{width:500,buttons:{'wikieditor-toolbar-tool-replace-button-findnext':function(e){$j(this).closest('.ui-dialog').data('dialogaction',e.target);$j(this).data('replaceCallback').call(this,'find');},'wikieditor-toolbar-tool-replace-button-replacenext':function(e){$j(this).closest('.ui-dialog').data('dialogaction',e.target);$j(this).data('replaceCallback').call(this,'replace');},'wikieditor-toolbar-tool-replace-button-replaceall':function(e){$j(this).closest('.ui-dialog').data('dialogaction',e.target);$j(this).data('replaceCallback').call(this,'replaceAll');},'wikieditor-toolbar-tool-replace-close':function(){$j(this).dialog('close');}},open:function(){$j(this).data('offset',0);$j('#wikieditor-toolbar-replace-search').focus();$j('#wikieditor-toolbar-replace-nomatch, #wikieditor-toolbar-replace-success, #wikieditor-toolbar-replace-emptysearch, #wikieditor-toolbar-replace-invalidregex').hide();if(!($j(this).data('onetimeonlystuff'))){$j(this).data('onetimeonlystuff',true);$j(this).closest('.ui-dialog').keypress(function(e){if((e.keyCode||e.which)==13){var button=$j(this).data('dialogaction')||$j(this).find('button:first');button.click();e.preventDefault();}});$j(this).closest('.ui-dialog').find('button').focus(function(){$j(this).closest('.ui-dialog').data('dialogaction',this);});} |
| 180 | +$textarea.textSelection('scrollToCaretPosition');$j(this).data('offset',mode=='replace'?newEnd:end);}});},dialog:{width:500,dialogClass:'wikiEditor-toolbar-dialog',buttons:{'wikieditor-toolbar-tool-replace-button-findnext':function(e){$j(this).closest('.ui-dialog').data('dialogaction',e.target);$j(this).data('replaceCallback').call(this,'find');},'wikieditor-toolbar-tool-replace-button-replacenext':function(e){$j(this).closest('.ui-dialog').data('dialogaction',e.target);$j(this).data('replaceCallback').call(this,'replace');},'wikieditor-toolbar-tool-replace-button-replaceall':function(e){$j(this).closest('.ui-dialog').data('dialogaction',e.target);$j(this).data('replaceCallback').call(this,'replaceAll');},'wikieditor-toolbar-tool-replace-close':function(){$j(this).dialog('close');}},open:function(){$j(this).data('offset',0);$j('#wikieditor-toolbar-replace-search').focus();$j('#wikieditor-toolbar-replace-nomatch, #wikieditor-toolbar-replace-success, #wikieditor-toolbar-replace-emptysearch, #wikieditor-toolbar-replace-invalidregex').hide();if(!($j(this).data('onetimeonlystuff'))){$j(this).data('onetimeonlystuff',true);$j(this).closest('.ui-dialog').keypress(function(e){if((e.keyCode||e.which)==13){var button=$j(this).data('dialogaction')||$j(this).find('button:first');button.click();e.preventDefault();}});$j(this).closest('.ui-dialog').find('button').focus(function(){$j(this).closest('.ui-dialog').data('dialogaction',this);});} |
179 | 181 | var dialog=$j(this).closest('.ui-dialog');var that=this;$j($j(this).data('context').$iframe[0].contentWindow.document).bind('keypress.srdialog',function(e){if((e.keyCode||e.which)==13){var button=dialog.data('dialogaction')||dialog.find('button:first');button.click();e.preventDefault();}else if((e.keyCode||e.which)==27){$j(that).dialog('close');}});},close:function(){$j($j(this).data('context').$iframe[0].contentWindow.document).unbind('keypress.srdialog');$j(this).data('context').$iframe[0].contentWindow.focus();$j(this).closest('.ui-dialog').data('dialogaction',false);}}}}});}});$j(document).ready(function(){if(!wgWikiEditorEnabledModules.templateEditor){return true;} |
180 | 182 | if($j.fn.wikiEditor){$j('textarea#wpTextbox1').wikiEditor('addModule','templateEditor');}}); |
\ No newline at end of file |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/WikiEditor/Modules/TemplateEditor/TemplateEditor.i18n.php |
— | — | @@ -195,7 +195,7 @@ |
196 | 196 | * @author Robby |
197 | 197 | */ |
198 | 198 | $messages['lb'] = array( |
199 | | - 'wikieditor-template-editor-preference' => "D'Änner vu Wiki-Schablounen op der Basis vu Formulairen aschalten", |
| 199 | + 'wikieditor-template-editor-preference' => "D'Ännere vu Wiki-Schablounen op der Basis vu Formulairen aschalten", |
200 | 200 | ); |
201 | 201 | |
202 | 202 | /** Macedonian (Македонски) |
— | — | @@ -333,15 +333,17 @@ |
334 | 334 | |
335 | 335 | /** Simplified Chinese (中文(简体)) |
336 | 336 | * @author Gaoxuewei |
| 337 | + * @author Liangent |
337 | 338 | */ |
338 | 339 | $messages['zh-hans'] = array( |
339 | | - 'wikieditor-template-editor-preference' => '启用维基模板的表单式编辑', |
| 340 | + 'wikieditor-template-editor-preference' => '启用wiki模板的表单式编辑', |
340 | 341 | ); |
341 | 342 | |
342 | 343 | /** Traditional Chinese (中文(繁體)) |
343 | 344 | * @author Gaoxuewei |
| 345 | + * @author Liangent |
344 | 346 | */ |
345 | 347 | $messages['zh-hant'] = array( |
346 | | - 'wikieditor-template-editor-preference' => '啟用維基模板的表單式編輯', |
| 348 | + 'wikieditor-template-editor-preference' => '啟用wiki模板的表單式編輯', |
347 | 349 | ); |
348 | 350 | |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/WikiEditor/Modules/Toolbar/Toolbar.i18n.php |
— | — | @@ -1757,7 +1757,7 @@ |
1758 | 1758 | 'wikieditor-toolbar-tool-link-title' => 'Ubaci link', |
1759 | 1759 | 'wikieditor-toolbar-tool-link-int' => 'Na wiki stranicu', |
1760 | 1760 | 'wikieditor-toolbar-tool-link-int-target' => 'Naslov stranice:', |
1761 | | - 'wikieditor-toolbar-tool-link-int-target-tooltip' => 'Unesite naslov stranice', |
| 1761 | + 'wikieditor-toolbar-tool-link-int-target-tooltip' => 'Naslov stranice ili URL', |
1762 | 1762 | 'wikieditor-toolbar-tool-link-int-text' => 'Tekst linka:', |
1763 | 1763 | 'wikieditor-toolbar-tool-link-int-text-tooltip' => 'Unesite tekst koji bi trebao biti prikazan', |
1764 | 1764 | 'wikieditor-toolbar-tool-link-ext' => 'Na vanjsku web stranicu', |
— | — | @@ -2794,7 +2794,7 @@ |
2795 | 2795 | 'wikieditor-toolbar-tool-link-title' => 'Link einfügen', |
2796 | 2796 | 'wikieditor-toolbar-tool-link-int' => 'Zu einer Wiki-Seite', |
2797 | 2797 | 'wikieditor-toolbar-tool-link-int-target' => 'Seitentitel:', |
2798 | | - 'wikieditor-toolbar-tool-link-int-target-tooltip' => 'Seitentitel eingeben', |
| 2798 | + 'wikieditor-toolbar-tool-link-int-target-tooltip' => 'Titel der Seite oder URL', |
2799 | 2799 | 'wikieditor-toolbar-tool-link-int-text' => 'Linktitel:', |
2800 | 2800 | 'wikieditor-toolbar-tool-link-int-text-tooltip' => 'Text eingeben, der angezeigt werden soll', |
2801 | 2801 | 'wikieditor-toolbar-tool-link-ext' => 'Zu einer externen Internetseite', |
— | — | @@ -4173,7 +4173,7 @@ |
4174 | 4174 | 'wikieditor-toolbar-tool-link-title' => 'Sartu lotura', |
4175 | 4175 | 'wikieditor-toolbar-tool-link-int' => 'Wiki orrialde batera', |
4176 | 4176 | 'wikieditor-toolbar-tool-link-int-target' => 'Orrialdearen izenburua:', |
4177 | | - 'wikieditor-toolbar-tool-link-int-target-tooltip' => 'Idatzi orriaren izenburua', |
| 4177 | + 'wikieditor-toolbar-tool-link-int-target-tooltip' => 'Orriaren izenburua edo URL', |
4178 | 4178 | 'wikieditor-toolbar-tool-link-int-text' => 'Lotutako testua:', |
4179 | 4179 | 'wikieditor-toolbar-tool-link-int-text-tooltip' => 'Idatzi erakutsi beharreko testua', |
4180 | 4180 | 'wikieditor-toolbar-tool-link-ext' => 'Kanpoko orrialde batera', |
— | — | @@ -4405,7 +4405,7 @@ |
4406 | 4406 | 'wikieditor-toolbar-tool-link-title' => 'Lisää linkki', |
4407 | 4407 | 'wikieditor-toolbar-tool-link-int' => 'Wikisivuun', |
4408 | 4408 | 'wikieditor-toolbar-tool-link-int-target' => 'Artikkelin otsikko:', |
4409 | | - 'wikieditor-toolbar-tool-link-int-target-tooltip' => 'Syötä sivun otsikko', |
| 4409 | + 'wikieditor-toolbar-tool-link-int-target-tooltip' => 'Sivun otsikko tai URL', |
4410 | 4410 | 'wikieditor-toolbar-tool-link-int-text' => 'Linkin teksti:', |
4411 | 4411 | 'wikieditor-toolbar-tool-link-int-text-tooltip' => 'Syötä näytettävä teksti', |
4412 | 4412 | 'wikieditor-toolbar-tool-link-ext' => 'Ulkoiseen sivustoon', |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/WikiEditor/Modules/Toolbar/Toolbar.js |
— | — | @@ -880,26 +880,27 @@ |
881 | 881 | } |
882 | 882 | return s.match( arguments.callee.regex ); |
883 | 883 | } |
| 884 | + // Updates the status indicator above the target link |
| 885 | + function updateWidget( status ) { |
| 886 | + $j( '#wikieditor-toolbar-link-int-target-status' ).children().hide(); |
| 887 | + $j( '#wikieditor-toolbar-link-int-target' ).parent() |
| 888 | + .removeClass( 'status-invalid status-external status-notexists status-exists status-loading' ); |
| 889 | + if ( status ) { |
| 890 | + $j( '#wikieditor-toolbar-link-int-target-status-' + status ).show(); |
| 891 | + $j( '#wikieditor-toolbar-link-int-target' ).parent().addClass( 'status-' + status ); |
| 892 | + } |
| 893 | + if ( status == 'invalid' ) { |
| 894 | + $j( '.ui-dialog:visible .ui-dialog-buttonpane button:first' ) |
| 895 | + .attr( 'disabled', true ) |
| 896 | + .addClass( 'disabled' ); |
| 897 | + } else { |
| 898 | + $j( '.ui-dialog:visible .ui-dialog-buttonpane button:first' ) |
| 899 | + .removeAttr('disabled') |
| 900 | + .removeClass('disabled'); |
| 901 | + } |
| 902 | + } |
884 | 903 | // Updates the UI to show if the page title being inputed by the user exists or not |
885 | 904 | function updateExistence() { |
886 | | - function updateWidget( status ) { |
887 | | - $j( '#wikieditor-toolbar-link-int-target-status' ).children().hide(); |
888 | | - $j( '#wikieditor-toolbar-link-int-target' ).parent() |
889 | | - .removeClass( 'status-invalid status-external status-notexists status-exists status-loading' ); |
890 | | - if ( status ) { |
891 | | - $j( '#wikieditor-toolbar-link-int-target-status-' + status ).show(); |
892 | | - $j( '#wikieditor-toolbar-link-int-target' ).parent().addClass( 'status-' + status ); |
893 | | - } |
894 | | - if ( status == 'invalid' ) { |
895 | | - $j( '.ui-dialog:visible .ui-dialog-buttonpane button:first' ) |
896 | | - .attr( 'disabled', true ) |
897 | | - .addClass( 'disabled' ); |
898 | | - } else { |
899 | | - $j( '.ui-dialog:visible .ui-dialog-buttonpane button:first' ) |
900 | | - .removeAttr('disabled') |
901 | | - .removeClass('disabled'); |
902 | | - } |
903 | | - } |
904 | 905 | // Abort previous request |
905 | 906 | var request = $j( '#wikieditor-toolbar-link-int-target-status' ).data( 'request' ); |
906 | 907 | if ( request ) { |
— | — | @@ -959,6 +960,12 @@ |
960 | 961 | } ) |
961 | 962 | ); |
962 | 963 | } |
| 964 | + $j( '#wikieditor-toolbar-link-type-int, #wikieditor-toolbar-link-type-ext' ).click( function() { |
| 965 | + if( $j( '#wikieditor-toolbar-link-type-ext' ).is( ':checked' ) ) |
| 966 | + updateWidget( 'external' ); |
| 967 | + if( $j( '#wikieditor-toolbar-link-type-int' ).is( ':checked' ) ) |
| 968 | + updateExistence(); |
| 969 | + }); |
963 | 970 | // Set labels of tabs based on rel values |
964 | 971 | var u = mw.usability; |
965 | 972 | $j(this).find( '[rel]' ).each( function() { |
— | — | @@ -1124,16 +1131,20 @@ |
1125 | 1132 | }, |
1126 | 1133 | dialog: { |
1127 | 1134 | width: 500, |
| 1135 | + dialogClass: 'wikiEditor-toolbar-dialog', |
1128 | 1136 | buttons: { |
1129 | 1137 | 'wikieditor-toolbar-tool-link-insert': function() { |
1130 | 1138 | function escapeInternalText( s ) { |
| 1139 | + // FIXME: Should this escape [[ too? Seems to work without that |
1131 | 1140 | return s.replace( /(]{2,})/g, '<nowiki>$1</nowiki>' ); |
1132 | 1141 | } |
1133 | 1142 | function escapeExternalTarget( s ) { |
1134 | 1143 | return s.replace( / /g, '%20' ) |
| 1144 | + .replace( /\[/g, '%5B' ) |
1135 | 1145 | .replace( /]/g, '%5D' ); |
1136 | 1146 | } |
1137 | 1147 | function escapeExternalText( s ) { |
| 1148 | + // FIXME: Should this escape [ too? Seems to work without that |
1138 | 1149 | return s.replace( /(]+)/g, '<nowiki>$1</nowiki>' ); |
1139 | 1150 | } |
1140 | 1151 | var insertText = ''; |
— | — | @@ -1401,6 +1412,7 @@ |
1402 | 1413 | }, |
1403 | 1414 | dialog: { |
1404 | 1415 | resizable: false, |
| 1416 | + dialogClass: 'wikiEditor-toolbar-dialog', |
1405 | 1417 | width: 590, |
1406 | 1418 | buttons: { |
1407 | 1419 | 'wikieditor-toolbar-tool-table-insert': function() { |
— | — | @@ -1633,6 +1645,7 @@ |
1634 | 1646 | }, |
1635 | 1647 | dialog: { |
1636 | 1648 | width: 500, |
| 1649 | + dialogClass: 'wikiEditor-toolbar-dialog', |
1637 | 1650 | buttons: { |
1638 | 1651 | 'wikieditor-toolbar-tool-replace-button-findnext': function( e ) { |
1639 | 1652 | $j(this).closest( '.ui-dialog' ).data( 'dialogaction', e.target ); |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/PrefStats/PrefStats.i18n.php |
— | — | @@ -1392,12 +1392,12 @@ |
1393 | 1393 | Кликнете на едно од нив за да ги видите статистиките за него.', |
1394 | 1394 | 'prefstats-noprefs' => 'Моментално не се следите никакви прилагодувања. |
1395 | 1395 | Конфигурирајте го $wgPrefStatsTrackPrefs за да следите прилагодувања.', |
1396 | | - 'prefstats-counters' => '* $1 {{PLURAL:$1|корисник ја има|корисници ја имаат}} вклучено оваа можност од кога е активирана статистиката на прилагодувања |
1397 | | -** $2 {{PLURAL:$2|корисник сеуште ја чува вклучена|корисници сеуште ја чуваат вклучена}} |
1398 | | -** $3 {{PLURAL:$3|корисникот во меѓувреме ја оневозможил|корисниците во меѓувреме ја оневозможиле}}', |
| 1396 | + 'prefstats-counters' => '* $1 {{PLURAL:$1|корисник ја има|корисници ја имаат}} вклучено оваа можност откога се активирани статистиките за прилагодувања |
| 1397 | +** $2 {{PLURAL:$2|корисник сè уште ја чува вклучена|корисници сè уште ја чуваат вклучена}} |
| 1398 | +** $3 {{PLURAL:$3|корисник во меѓувреме ја оневозможил|корисници во меѓувреме ја оневозможиле}}', |
1399 | 1399 | 'prefstats-counters-expensive' => '* $1 {{PLURAL:$1|корисник ја има|корисници ја имаат}} вклучено оваа можност од кога е активирана статистиката на прилагодувања |
1400 | 1400 | ** $2 {{PLURAL:$2|корисник сè уште ја чува вклучена|корисници сè уште ја чуваат вклучена}} |
1401 | | -** $3 {{PLURAL:$3|корисникот во меѓувреме ја оневозможил|корисниците во меѓувреме ја оневозможиле}} |
| 1401 | +** $3 {{PLURAL:$3|корисник во меѓувреме ја оневозможил|корисници во меѓувреме ја оневозможиле}} |
1402 | 1402 | * Вкупно $4 {{PLURAL:$4|корисник ја има вклучено оваа можност|корисници ја имаат вклучено оваа можност}}', |
1403 | 1403 | 'prefstats-xaxis' => 'Времетрање (часови)', |
1404 | 1404 | 'prefstats-factors' => 'Поглед по: $1', |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/js/plugins.combined.js |
— | — | @@ -6513,7 +6513,7 @@ |
6514 | 6514 | } |
6515 | 6515 | // Check over each browser condition to determine if we are running in a compatible client |
6516 | 6516 | var browser = $.wikiEditor.browsers[$( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'][$.browser.name]; |
6517 | | - for ( condition in browser ) { |
| 6517 | + for ( var condition in browser ) { |
6518 | 6518 | var op = browser[condition][0]; |
6519 | 6519 | var val = browser[condition][1]; |
6520 | 6520 | if ( typeof val == 'string' ) { |
— | — | @@ -6542,7 +6542,7 @@ |
6543 | 6543 | 'autoMsg': function( object, property ) { |
6544 | 6544 | // Accept array of possible properties, of which the first one found will be used |
6545 | 6545 | if ( typeof property == 'object' ) { |
6546 | | - for ( i in property ) { |
| 6546 | + for ( var i in property ) { |
6547 | 6547 | if ( property[i] in object || property[i] + 'Msg' in object ) { |
6548 | 6548 | property = property[i]; |
6549 | 6549 | break; |
— | — | @@ -6623,7 +6623,13 @@ |
6624 | 6624 | // Unique numeric ID of this instance used both for looking up and differentiating instances of wikiEditor |
6625 | 6625 | 'instance': $.wikiEditor.instances.push( $(this) ) - 1, |
6626 | 6626 | // Array mapping elements in the textarea to character offsets |
6627 | | - 'offsets': null |
| 6627 | + 'offsets': null, |
| 6628 | + // Cache for context.fn.htmlToText() |
| 6629 | + 'htmlToTextMap': {}, |
| 6630 | + // The previous HTML of the iframe, stored to detect whether something really changed. |
| 6631 | + 'oldHTML': null, |
| 6632 | + // Same for delayedChange() |
| 6633 | + 'oldDelayedHTML': null |
6628 | 6634 | }; |
6629 | 6635 | |
6630 | 6636 | /* |
— | — | @@ -6647,12 +6653,12 @@ |
6648 | 6654 | } else if ( typeof data == 'object' ) { |
6649 | 6655 | modules = data; |
6650 | 6656 | } |
6651 | | - for ( module in modules ) { |
| 6657 | + for ( var module in modules ) { |
6652 | 6658 | // Check for the existance of an available module with a matching name and a create function |
6653 | 6659 | if ( typeof module == 'string' && module in $.wikiEditor.modules ) { |
6654 | 6660 | // Extend the context's core API with this module's own API calls |
6655 | 6661 | if ( 'api' in $.wikiEditor.modules[module] ) { |
6656 | | - for ( call in $.wikiEditor.modules[module].api ) { |
| 6662 | + for ( var call in $.wikiEditor.modules[module].api ) { |
6657 | 6663 | // Modules may not overwrite existing API functions - first come, first serve |
6658 | 6664 | if ( !( call in context.api ) ) { |
6659 | 6665 | context.api[call] = $.wikiEditor.modules[module].api[call]; |
— | — | @@ -6686,12 +6692,23 @@ |
6687 | 6693 | */ |
6688 | 6694 | 'change': function( event ) { |
6689 | 6695 | event.data.scope = 'division'; |
6690 | | - context.fn.purgeOffsets(); |
| 6696 | + var newHTML = context.$content.html(); |
| 6697 | + if ( context.oldHTML != newHTML ) { |
| 6698 | + context.fn.purgeOffsets(); |
| 6699 | + context.oldHTML = newHTML; |
| 6700 | + event.data.scope = 'realchange'; |
| 6701 | + } |
6691 | 6702 | return true; |
6692 | 6703 | }, |
6693 | 6704 | 'delayedChange': function( event ) { |
6694 | | - // Redirect - since we want the same functionality |
6695 | | - return context.evt.change( event ); |
| 6705 | + event.data.scope = 'division'; |
| 6706 | + var newHTML = context.$content.html(); |
| 6707 | + if ( context.oldDelayedHTML != newHTML ) { |
| 6708 | + context.fn.purgeOffsets(); |
| 6709 | + context.oldDelayedHTML = newHTML; |
| 6710 | + event.data.scope = 'realchange'; |
| 6711 | + } |
| 6712 | + return true; |
6696 | 6713 | } |
6697 | 6714 | }; |
6698 | 6715 | |
— | — | @@ -6717,7 +6734,7 @@ |
6718 | 6735 | } |
6719 | 6736 | } |
6720 | 6737 | // Pass the event around to all modules activated on this context |
6721 | | - for ( module in context.modules ) { |
| 6738 | + for ( var module in context.modules ) { |
6722 | 6739 | if ( |
6723 | 6740 | module in $.wikiEditor.modules && |
6724 | 6741 | 'evt' in $.wikiEditor.modules[module] && |
— | — | @@ -6784,22 +6801,71 @@ |
6785 | 6802 | .appendTo( context.$ui ); |
6786 | 6803 | }, |
6787 | 6804 | 'htmlToText': function( html ) { |
| 6805 | + // This function is slow for large inputs, so aggressively cache input/output pairs |
| 6806 | + if ( html in context.htmlToTextMap ) { |
| 6807 | + return context.htmlToTextMap[html]; |
| 6808 | + } |
| 6809 | + var origHTML = html; |
| 6810 | + |
6788 | 6811 | // We use this elaborate trickery for cross-browser compatibility |
6789 | 6812 | // IE does overzealous whitespace collapsing for $( '<pre />' ).html( html ); |
6790 | | - var $pre = $( '<pre>' + |
6791 | | - html |
| 6813 | + // We also do <br> and easy cases for <p> conversion here, complicated cases are handled later |
| 6814 | + html = html |
6792 | 6815 | .replace( /\r?\n/g, "" ) // IE7 inserts newlines before block elements |
6793 | | - .replace( /\<br[^\>]*\>/gi, "\n" ) |
6794 | 6816 | .replace( / /g, " " ) // We inserted these to prevent IE from collapsing spaces |
6795 | | - .replace( /\<p[^\>]*\>/gi, "\n" ) // IE uses </p><p> for user-inserted line breaks |
6796 | | - .replace( /\<\/p[^\>]*\>/gi, "" ) |
6797 | | - .replace( /\<div[^\>]*\>/gi, "\n" ) // Webkit uses </p><p> for user-inserted line breaks |
6798 | | - .replace( /\<\/div[^\>]*\>/gi, "" ) |
6799 | | - + '</pre>' ); |
6800 | | - // Get rid of the noincludes when getting text |
| 6817 | + .replace( /\<br[^\>]*\>/gi, "\n" ) // <br> conversion |
| 6818 | + .replace( /\<\/p\>\<p\>/gi, "\n" ) // Easy case for <p> conversion |
| 6819 | + .replace( /\<\/p\>(\n*)\<p\>/gi, "$1\n" ); |
| 6820 | + // Save leading and trailing whitespace now and restore it later. IE eats it all, and even Firefox |
| 6821 | + // won't leave everything alone |
| 6822 | + var leading = html.match( /^\s*/ )[0]; |
| 6823 | + var trailing = html.match( /\s*$/ )[0]; |
| 6824 | + html = html.substr( leading.length, html.length - leading.length - trailing.length ); |
| 6825 | + var $pre = $( '<pre>' + html + '</pre>' ); |
6801 | 6826 | $pre.find( '.wikiEditor-noinclude' ).each( function() { $( this ).remove(); } ); |
6802 | | - $pre.find( '.wikiEditor-tab' ).each( function() { $( this ).text( "\t" ) } ); |
6803 | | - return $pre.text(); |
| 6827 | + // Convert tabs, <p>s and <br>s back |
| 6828 | + $pre.find( '.wikiEditor-tab' ).each( function() { $( this ).text( "\t" ); } ); |
| 6829 | + $pre.find( 'br' ).each( function() { $( this ).replaceWith( "\n" ); } ); |
| 6830 | + // Converting <p>s is wrong if there's nothing before them, so check that. |
| 6831 | + // .find( '* + p' ) isn't good enough because textnodes aren't considered |
| 6832 | + $pre.find( 'p' ).each( function() { |
| 6833 | + if ( this.previousSibling || this.parentNode != $pre.get( 0 ) ) { |
| 6834 | + var text = $( this ).text(); |
| 6835 | + // If this <p> is preceded by some text, add a \n at the beginning, and if |
| 6836 | + // it's followed by a textnode, add a \n at the end |
| 6837 | + // We need the traverser because there can be other weird stuff in between |
| 6838 | + |
| 6839 | + // Check for preceding text |
| 6840 | + // FIXME: Add an option to disable depth checking, -10 is a hack |
| 6841 | + var t = new context.fn.rawTraverser( this.firstChild, -10, this ).prev(); |
| 6842 | + while ( t && t.node.nodeName != '#text' && t.node.nodeName != 'BR' && t.node.nodeName != 'P' ) { |
| 6843 | + t = t.prev(); |
| 6844 | + } |
| 6845 | + if ( t ) { |
| 6846 | + text = "\n" + text; |
| 6847 | + } |
| 6848 | + |
| 6849 | + // Check for following text |
| 6850 | + t = new context.fn.rawTraverser( this.lastChild, -10, this ).next(); |
| 6851 | + while ( t && t.node.nodeName != '#text' && t.node.nodeName != 'BR' && t.node.nodeName != 'P' ) { |
| 6852 | + t = t.next(); |
| 6853 | + } |
| 6854 | + if ( t && !t.inP && t.node.nodeName == '#text' && t.node.nodeValue.charAt( 0 ) != '\n' |
| 6855 | + && t.node.nodeValue.charAt( 0 ) != '\r' ) { |
| 6856 | + text += "\n"; |
| 6857 | + } |
| 6858 | + $( this ).text( text ); |
| 6859 | + } |
| 6860 | + } ); |
| 6861 | + var retval; |
| 6862 | + if ( $.browser.msie ) { |
| 6863 | + // IE aggressively collapses whitespace in .text() after having done DOM manipulation, |
| 6864 | + // but for some crazy reason this does work. Also convert \r back to \n |
| 6865 | + retval = $( '<pre>' + $pre.html() + '</pre>' ).text().replace( /\r/g, '\n' ); |
| 6866 | + } else { |
| 6867 | + retval = $pre.text(); |
| 6868 | + } |
| 6869 | + return context.htmlToTextMap[origHTML] = leading + retval + trailing; |
6804 | 6870 | }, |
6805 | 6871 | |
6806 | 6872 | /* |
— | — | @@ -6824,6 +6890,17 @@ |
6825 | 6891 | if ( context.$iframe[0].contentWindow.getSelection ) { |
6826 | 6892 | // Firefox and Opera |
6827 | 6893 | retval = context.$iframe[0].contentWindow.getSelection(); |
| 6894 | + if ( $.browser.opera ) { |
| 6895 | + // Opera strips newlines in getSelection(), so we need something more sophisticated |
| 6896 | + if ( retval.rangeCount > 0 ) { |
| 6897 | + retval = context.fn.htmlToText( $( '<pre />' ) |
| 6898 | + .append( retval.getRangeAt( 0 ).cloneContents() ) |
| 6899 | + .html() |
| 6900 | + ); |
| 6901 | + } else { |
| 6902 | + retval = ''; |
| 6903 | + } |
| 6904 | + } |
6828 | 6905 | } else if ( context.$iframe[0].contentWindow.document.selection ) { // should come last; Opera! |
6829 | 6906 | // IE |
6830 | 6907 | retval = context.$iframe[0].contentWindow.document.selection.createRange(); |
— | — | @@ -6867,25 +6944,47 @@ |
6868 | 6945 | // Firefox and Opera |
6869 | 6946 | var range = context.$iframe[0].contentWindow.getSelection().getRangeAt( 0 ); |
6870 | 6947 | if ( options.ownline ) { |
| 6948 | + // We need to figure out if the cursor is at the start or end of a line |
| 6949 | + var atStart = false, atEnd = false; |
6871 | 6950 | var body = context.$content.get( 0 ); |
6872 | | - // TODO: This'll probably break with syntax highlighting |
6873 | | - // When the selection starts at the beginning of a line, it'll have either |
6874 | | - // startOffset == 0 or startContainer == body |
6875 | | - if ( range.startOffset != 0 && range.startContainer != body ) { |
| 6951 | + if ( range.startOffset == 0 ) { |
| 6952 | + // Start of a line |
| 6953 | + // FIXME: Not necessarily the case with syntax highlighting or |
| 6954 | + // template collapsing |
| 6955 | + atStart = true; |
| 6956 | + } else if ( range.startContainer == body ) { |
| 6957 | + // Look up the node just before the start of the selection |
| 6958 | + // If it's a <BR>, we're at the start of a line that starts with a |
| 6959 | + // block element; if not, we're at the end of a line |
| 6960 | + var n = body.firstChild; |
| 6961 | + for ( var i = 0; i < range.startOffset - 1 && n; i++ ) { |
| 6962 | + n = n.nextSibling; |
| 6963 | + } |
| 6964 | + if ( n && n.nodeName == 'BR' ) { |
| 6965 | + atStart = true; |
| 6966 | + } else { |
| 6967 | + atEnd = true; |
| 6968 | + } |
| 6969 | + } else if ( range.startContainer.nodeName == '#text' && |
| 6970 | + range.startOffset == range.startContainer.nodeValue.length ) { |
| 6971 | + // Apparently this happens when splitting text nodes |
| 6972 | + atEnd = true; |
| 6973 | + } |
| 6974 | + |
| 6975 | + if ( !atStart ) { |
6876 | 6976 | pre = "\n" + options.pre; |
6877 | 6977 | } |
6878 | | - // TODO: Will this still work with syntax highlighting? |
6879 | | - // When the selection ends at the end of a line, it'll have endContainer == body |
6880 | | - // and endOffset != 0 |
6881 | | - if ( range.endContainer != body || range.endOffset == 0 ) { |
| 6978 | + if ( !atEnd ) { |
6882 | 6979 | post += "\n"; |
6883 | 6980 | } |
6884 | 6981 | } |
6885 | 6982 | var insertText = ""; |
6886 | 6983 | if ( options.splitlines ) { |
6887 | | - for( var i = 0; i < selTextArr.length; i++ ) { |
6888 | | - insertText = insertText + pre + selTextArr[i] + post; |
6889 | | - if( i != selTextArr.length - 1 ) insertText += "\n"; |
| 6984 | + for( var j = 0; j < selTextArr.length; j++ ) { |
| 6985 | + insertText = insertText + pre + selTextArr[j] + post; |
| 6986 | + if( j != selTextArr.length - 1 ) { |
| 6987 | + insertText += "\n"; |
| 6988 | + } |
6890 | 6989 | } |
6891 | 6990 | } else { |
6892 | 6991 | insertText = pre + selText + post; |
— | — | @@ -6931,9 +7030,9 @@ |
6932 | 7031 | // TODO: Clean this up. Duplicate code due to the pre-existing browser specific structure of this function |
6933 | 7032 | var insertText = ""; |
6934 | 7033 | if ( options.splitlines ) { |
6935 | | - for( var i = 0; i < selTextArr.length; i++ ) { |
6936 | | - insertText = insertText + pre + selTextArr[i] + post; |
6937 | | - if( i != selTextArr.length - 1 ) { |
| 7034 | + for( var j = 0; j < selTextArr.length; j++ ) { |
| 7035 | + insertText = insertText + pre + selTextArr[j] + post; |
| 7036 | + if( j != selTextArr.length - 1 ) { |
6938 | 7037 | insertText += "\n"; |
6939 | 7038 | } |
6940 | 7039 | } |
— | — | @@ -7058,14 +7157,14 @@ |
7059 | 7158 | */ |
7060 | 7159 | |
7061 | 7160 | /** |
7062 | | - * Get the first element before the selection matching a certain selector. |
7063 | | - * @param selector Selector to match. Defaults to '*' |
| 7161 | + * Get the first element before the selection that's in a certain class |
| 7162 | + * @param classname Class to match. Defaults to '', meaning any class |
7064 | 7163 | * @param strict If true, the element the selection starts in cannot match (default: false) |
7065 | 7164 | * @return jQuery object |
7066 | 7165 | */ |
7067 | | - 'beforeSelection': function( selector, strict ) { |
7068 | | - if ( typeof selector == 'undefined' ) { |
7069 | | - selector = '*'; |
| 7166 | + 'beforeSelection': function( classname, strict ) { |
| 7167 | + if ( typeof classname == 'undefined' ) { |
| 7168 | + classname = ''; |
7070 | 7169 | } |
7071 | 7170 | var e, offset; |
7072 | 7171 | if ( context.$iframe[0].contentWindow.getSelection ) { |
— | — | @@ -7076,7 +7175,7 @@ |
7077 | 7176 | // Start at the selection's start and traverse the DOM backwards |
7078 | 7177 | // This is done by traversing an element's children first, then the element itself, then its parent |
7079 | 7178 | e = selection.getRangeAt( 0 ).startContainer; |
7080 | | - offset = selection.startOffset; |
| 7179 | + offset = selection.getRangeAt( 0 ).startOffset; |
7081 | 7180 | } else { |
7082 | 7181 | return $( [] ); |
7083 | 7182 | } |
— | — | @@ -7091,7 +7190,7 @@ |
7092 | 7191 | // not in the iframe |
7093 | 7192 | try { |
7094 | 7193 | range2.setEndPoint( 'EndToStart', range ); |
7095 | | - } catch ( e ) { |
| 7194 | + } catch ( ex ) { |
7096 | 7195 | return $( [] ); |
7097 | 7196 | } |
7098 | 7197 | var seekPos = context.fn.htmlToText( range2.htmlText ).length; |
— | — | @@ -7115,9 +7214,14 @@ |
7116 | 7215 | } |
7117 | 7216 | e = newE || e; |
7118 | 7217 | } |
| 7218 | + |
| 7219 | + // We'd normally use if( $( e ).hasClass( class ) in the while loop, but running the jQuery |
| 7220 | + // constructor thousands of times is very inefficient |
| 7221 | + var classStr = ' ' + classname + ' '; |
7119 | 7222 | while ( e ) { |
7120 | | - if ( $( e ).is( selector ) && !strict ) |
| 7223 | + if ( !strict && ( !classname || ( ' ' + e.className + ' ' ).indexOf( classStr ) != -1 ) ) { |
7121 | 7224 | return $( e ); |
| 7225 | + } |
7122 | 7226 | var next = e.previousSibling; |
7123 | 7227 | while ( next && next.lastChild ) { |
7124 | 7228 | next = next.lastChild; |
— | — | @@ -7128,8 +7232,88 @@ |
7129 | 7233 | return $( [] ); |
7130 | 7234 | }, |
7131 | 7235 | /** |
| 7236 | + * Object used by traverser(). Don't use this unless you know what you're doing |
| 7237 | + */ |
| 7238 | + 'rawTraverser': function( node, depth, inP ) { |
| 7239 | + this.node = node; |
| 7240 | + this.depth = depth; |
| 7241 | + this.inP = inP; |
| 7242 | + this.next = function() { |
| 7243 | + var p = this.node; |
| 7244 | + var nextDepth = this.depth; |
| 7245 | + var nextInP = this.inP; |
| 7246 | + while ( p && !p.nextSibling ) { |
| 7247 | + p = p.parentNode; |
| 7248 | + nextDepth--; |
| 7249 | + if ( nextDepth == 0 ) { |
| 7250 | + // We're back at the start node |
| 7251 | + p = null; |
| 7252 | + } |
| 7253 | + if ( p && p.nodeName == "P" ) { |
| 7254 | + nextInP = null; |
| 7255 | + } |
| 7256 | + } |
| 7257 | + p = p ? p.nextSibling : null; |
| 7258 | + if ( p && p.nodeName == "P" ) { |
| 7259 | + nextInP = p; |
| 7260 | + } |
| 7261 | + do { |
| 7262 | + // Filter nodes with the wikiEditor-noinclude class |
| 7263 | + // Don't use $( p ).hasClass( 'wikiEditor-noinclude' ) because |
| 7264 | + // $() is slow in a tight loop |
| 7265 | + while ( p && ( ' ' + p.className + ' ' ).indexOf( ' wikiEditor-noinclude ' ) != -1 ) { |
| 7266 | + p = p.nextSibling; |
| 7267 | + } |
| 7268 | + if ( p && p.firstChild ) { |
| 7269 | + p = p.firstChild; |
| 7270 | + nextDepth++; |
| 7271 | + if ( p.nodeName == "P" ) { |
| 7272 | + nextInP = p; |
| 7273 | + } |
| 7274 | + } |
| 7275 | + } while ( p && p.firstChild ); |
| 7276 | + return p ? new context.fn.rawTraverser( p, nextDepth, nextInP ) : null; |
| 7277 | + }; |
| 7278 | + this.prev = function() { |
| 7279 | + var p = this.node; |
| 7280 | + var prevDepth = this.depth; |
| 7281 | + var prevInP = this.inP; |
| 7282 | + while ( p && !p.previousSibling ) { |
| 7283 | + p = p.parentNode; |
| 7284 | + prevDepth--; |
| 7285 | + if ( prevDepth == 0 ) { |
| 7286 | + // We're back at the start node |
| 7287 | + p = null; |
| 7288 | + } |
| 7289 | + if ( p && p.nodeName == "P" ) { |
| 7290 | + prevInP = null; |
| 7291 | + } |
| 7292 | + } |
| 7293 | + p = p ? p.previousSibling : null; |
| 7294 | + if ( p && p.nodeName == "P" ) { |
| 7295 | + prevInP = p; |
| 7296 | + } |
| 7297 | + do { |
| 7298 | + // Filter nodes with the wikiEditor-noinclude class |
| 7299 | + // Don't use $( p ).hasClass( 'wikiEditor-noinclude' ) because |
| 7300 | + // $() is slow in a tight loop |
| 7301 | + while ( p && ( ' ' + p.className + ' ' ).indexOf( ' wikiEditor-noinclude ' ) != -1 ) { |
| 7302 | + p = p.previousSibling; |
| 7303 | + } |
| 7304 | + if ( p && p.lastChild ) { |
| 7305 | + p = p.lastChild; |
| 7306 | + prevDepth++; |
| 7307 | + if ( p.nodeName == "P" ) { |
| 7308 | + prevInP = p; |
| 7309 | + } |
| 7310 | + } |
| 7311 | + } while ( p && p.lastChild ); |
| 7312 | + return p ? new context.fn.rawTraverser( p, prevDepth, prevInP ) : null; |
| 7313 | + }; |
| 7314 | + }, |
| 7315 | + /** |
7132 | 7316 | * Get an object used to traverse the leaf nodes in the iframe DOM. This traversal skips leaf nodes |
7133 | | - * inside an element with the wikiEditor-noinclude class. |
| 7317 | + * inside an element with the wikiEditor-noinclude class. This basically wraps rawTraverser |
7134 | 7318 | * |
7135 | 7319 | * Usage: |
7136 | 7320 | * var t = context.fn.traverser( context.$content ); |
— | — | @@ -7139,48 +7323,10 @@ |
7140 | 7324 | * // Trying to advance past the end will set t.node to null |
7141 | 7325 | */ |
7142 | 7326 | 'traverser': function( start ) { |
7143 | | - function Traverser( node, depth, inP ) { |
7144 | | - this.node = node; |
7145 | | - this.depth = depth; |
7146 | | - this.inP = inP; |
7147 | | - this.next = function() { |
7148 | | - var p = this.node; |
7149 | | - var nextDepth = this.depth; |
7150 | | - var nextInP = this.inP; |
7151 | | - while ( p && !p.nextSibling ) { |
7152 | | - if ( p.nodeName == "P" ) { |
7153 | | - nextInP = false; |
7154 | | - } |
7155 | | - p = p.parentNode; |
7156 | | - nextDepth--; |
7157 | | - if ( nextDepth == 0 ) { |
7158 | | - // We're back at the start node |
7159 | | - p = null; |
7160 | | - } |
7161 | | - } |
7162 | | - p = p ? p.nextSibling : null; |
7163 | | - do { |
7164 | | - // Filter nodes with the wikiEditor-noinclude class |
7165 | | - // Don't use $( p ).hasClass( 'wikiEditor-noinclude' ) because |
7166 | | - // $() is slow in a tight loop |
7167 | | - while ( p && ( ' ' + p.className + ' ' ).indexOf( ' wikiEditor-noinclude ' ) != -1 ) { |
7168 | | - p = p.nextSibling; |
7169 | | - } |
7170 | | - if ( p && p.firstChild ) { |
7171 | | - p = p.firstChild; |
7172 | | - nextDepth++; |
7173 | | - if ( p.nodeName == "P" ) { |
7174 | | - nextInP = true; |
7175 | | - } |
7176 | | - } |
7177 | | - } while ( p && p.firstChild ); |
7178 | | - return p ? new Traverser( p, nextDepth, nextInP ) : null; |
7179 | | - }; |
7180 | | - } |
7181 | 7327 | // Find the leftmost leaf node in the tree |
7182 | 7328 | var node = start.jquery ? start.get( 0 ) : start; |
7183 | 7329 | var depth = 0; |
7184 | | - var inP = node.nodeName == "P"; |
| 7330 | + var inP = node.nodeName == "P" ? node : null; |
7185 | 7331 | do { |
7186 | 7332 | // Filter nodes with the wikiEditor-noinclude class |
7187 | 7333 | // Don't use $( p ).hasClass( 'wikiEditor-noinclude' ) because |
— | — | @@ -7192,11 +7338,11 @@ |
7193 | 7339 | node = node.firstChild; |
7194 | 7340 | depth++; |
7195 | 7341 | if ( node.nodeName == "P" ) { |
7196 | | - inP = true; |
| 7342 | + inP = node; |
7197 | 7343 | } |
7198 | 7344 | } |
7199 | 7345 | } while ( node && node.firstChild ); |
7200 | | - return new Traverser( node, depth, inP ); |
| 7346 | + return new context.fn.rawTraverser( node, depth, inP ); |
7201 | 7347 | }, |
7202 | 7348 | 'getOffset': function( offset ) { |
7203 | 7349 | if ( !context.offsets ) { |
— | — | @@ -7220,7 +7366,7 @@ |
7221 | 7367 | var base = context.offsets[lowerBound]; |
7222 | 7368 | return context.offsets[offset] = { |
7223 | 7369 | 'node': base.node, |
7224 | | - 'offset': base.offset + offset - o, |
| 7370 | + 'offset': base.offset + offset - lowerBound, |
7225 | 7371 | 'length': base.length, |
7226 | 7372 | 'depth': base.depth, |
7227 | 7373 | 'lastTextNode': base.lastTextNode, |
— | — | @@ -7235,13 +7381,13 @@ |
7236 | 7382 | var t = context.fn.traverser( context.$content ); |
7237 | 7383 | var pos = 0, lastTextNode = null, lastTextNodeDepth = null; |
7238 | 7384 | while ( t ) { |
7239 | | - if ( t.node.nodeName != '#text' && t.node.nodeName != 'BR' ) { |
| 7385 | + if ( t.node.nodeName != '#text' && t.node.nodeName != 'BR' && t.node.nodeName != 'P' ) { |
7240 | 7386 | t = t.next(); |
7241 | 7387 | continue; |
7242 | 7388 | } |
7243 | 7389 | var nextPos = t.node.nodeName == '#text' ? pos + t.node.nodeValue.length : pos + 1; |
7244 | 7390 | var nextT = t.next(); |
7245 | | - var leavingP = t.inP && nextT && !nextT.inP; |
| 7391 | + var leavingP = t.node.nodeName != 'P' && t.inP && nextT && ( !nextT.inP || nextT.inP != t.inP ); |
7246 | 7392 | context.offsets[pos] = { |
7247 | 7393 | 'node': t.node, |
7248 | 7394 | 'offset': 0, |
— | — | @@ -7311,7 +7457,7 @@ |
7312 | 7458 | // Setup the intial view |
7313 | 7459 | context.view = 'wikitext'; |
7314 | 7460 | // Trigger the "resize" event anytime the window is resized |
7315 | | - $( window ).resize( function( event ) { context.fn.trigger( 'resize', event ) } ); |
| 7461 | + $( window ).resize( function( event ) { context.fn.trigger( 'resize', event ); } ); |
7316 | 7462 | // Create an iframe in place of the text area |
7317 | 7463 | context.$iframe = $( '<iframe></iframe>' ) |
7318 | 7464 | .attr( { |
— | — | @@ -7347,7 +7493,13 @@ |
7348 | 7494 | // If we just do "context.$content.text( context.$textarea.val() )", Internet Explorer will strip out the |
7349 | 7495 | // whitespace charcters, specifically "\n" - so we must manually encode the text and append it |
7350 | 7496 | // TODO: Refactor this into a textToHtml() function |
7351 | | - var html = context.$textarea.val(); |
| 7497 | + // Because we're gonna insert instances of <br>, and <span class="wikiEditor-tab"></span>, |
| 7498 | + // we have to escape existing instances first. This'll cause them to be double-escaped, which we |
| 7499 | + // fix later on |
| 7500 | + var html = context.$textarea.val() |
| 7501 | + .replace( / /g, '&nbsp;' ) |
| 7502 | + .replace( /\<br\>/g, '<br>' ) |
| 7503 | + .replace( /\<span class="wikiEditor-tab"\>\<\/span\>/g, '<span class="wikiEditor-tab"></span>' ); |
7352 | 7504 | // We must do some extra processing on IE to avoid dirty diffs, specifically IE will collapse leading spaces |
7353 | 7505 | if ( $.browser.msie ) { |
7354 | 7506 | // Browser sniffing is not ideal, but executing this code on a non-broken browser doesn't cause harm |
— | — | @@ -7363,11 +7515,20 @@ |
7364 | 7516 | } |
7365 | 7517 | // Use a dummy div to escape all entities |
7366 | 7518 | // This'll also escape <br>, <span> and , so we unescape those after |
7367 | | - html = $( '<div />' ).text( html.replace( /\r?\n/g, '<br>' ) ).html() |
| 7519 | + // We also need to unescape the doubly-escaped things mentioned above |
| 7520 | + html = $( '<div />' ).text( '<p>' + html.replace( /\r?\n/g, '</p><p>' ) + '</p>' ).html() |
7368 | 7521 | .replace( /&nbsp;/g, ' ' ) |
7369 | | - .replace( /<br>/g, '<br>' ) |
7370 | | - .replace( /<span class="wikiEditor-tab"><\/span>/g, '<span class="wikiEditor-tab"></span>' ); |
| 7522 | + // Allow p tags to survive encoding |
| 7523 | + .replace( /<p>/g, '<p>' ) |
| 7524 | + .replace( /<\/p>/g, '</p>' ) |
| 7525 | + // Empty p tags should just be br tags |
| 7526 | + .replace( /<p><\/p>/g, '<br>' ) |
| 7527 | + .replace( /<span class="wikiEditor-tab"><\/span>/g, '<span class="wikiEditor-tab"></span>' ) |
| 7528 | + .replace( /&amp;nbsp;/g, '&nbsp;' ) |
| 7529 | + .replace( /&lt;br&gt;/g, '<br>' ) |
| 7530 | + .replace( /&lt;span class=&quot;wikiEditor-tab&quot;&gt;&lt;\/span&gt;/g, '<span class="wikiEditor-tab"></span>' ); |
7371 | 7531 | context.$content.html( html ); |
| 7532 | + context.oldHTML = html; |
7372 | 7533 | |
7373 | 7534 | // Reflect direction of parent frame into child |
7374 | 7535 | if ( $( 'body' ).is( '.rtl' ) ) { |
— | — | @@ -7400,19 +7561,19 @@ |
7401 | 7562 | window.onbeforeunload = function() { |
7402 | 7563 | context.$textarea.val( context.$textarea.textSelection( 'getContents' ) ); |
7403 | 7564 | return context.fallbackWindowOnBeforeUnload ? context.fallbackWindowOnBeforeUnload() : null; |
7404 | | - } |
| 7565 | + }; |
7405 | 7566 | } |
7406 | 7567 | |
7407 | 7568 | /* API Execution */ |
7408 | 7569 | |
7409 | 7570 | // Since javascript gives arguments as an object, we need to convert them so they can be used more easily |
7410 | | -arguments = $.makeArray( arguments ); |
| 7571 | +var args = $.makeArray( arguments ); |
7411 | 7572 | // There would need to be some arguments if the API is being called |
7412 | | -if ( arguments.length > 0 ) { |
| 7573 | +if ( args.length > 0 ) { |
7413 | 7574 | // Handle API calls |
7414 | | - var call = arguments.shift(); |
| 7575 | + var call = args.shift(); |
7415 | 7576 | if ( call in context.api ) { |
7416 | | - context.api[call]( context, typeof arguments[0] == 'undefined' ? {} : arguments[0] ); |
| 7577 | + context.api[call]( context, typeof args[0] == 'undefined' ? {} : args[0] ); |
7417 | 7578 | } |
7418 | 7579 | } |
7419 | 7580 | |
— | — | @@ -7607,7 +7768,7 @@ |
7608 | 7769 | * ; Definition |
7609 | 7770 | * : Definition |
7610 | 7771 | */ |
7611 | | - if ( event.data.scope == 'division' ) { |
| 7772 | + if ( event.data.scope == 'realchange' ) { |
7612 | 7773 | $.wikiEditor.modules.highlight.fn.scan( context, "" ); |
7613 | 7774 | $.wikiEditor.modules.highlight.fn.mark( context, "", "" ); |
7614 | 7775 | } |
— | — | @@ -7628,7 +7789,7 @@ |
7629 | 7790 | * @param config Configuration object to create module from |
7630 | 7791 | */ |
7631 | 7792 | create: function( context, config ) { |
7632 | | - // hook $.wikiEditor.modules.highlight.evt.change to context.evt.change |
| 7793 | + context.modules.highlight.markersStr = ''; |
7633 | 7794 | }, |
7634 | 7795 | /** |
7635 | 7796 | * Divides text into divisions |
— | — | @@ -7717,6 +7878,7 @@ |
7718 | 7879 | * @param tokens |
7719 | 7880 | */ |
7720 | 7881 | // FIXME: What do division and tokens do? |
| 7882 | + // TODO: Document the scan() and mark() APIs somewhere |
7721 | 7883 | mark: function( context, division, tokens ) { |
7722 | 7884 | // Reset markers |
7723 | 7885 | var markers = context.modules.highlight.markers = []; |
— | — | @@ -7724,7 +7886,21 @@ |
7725 | 7887 | context.fn.trigger( 'mark' ); |
7726 | 7888 | markers.sort( function( a, b ) { return a.start - b.start || a.end - b.end; } ); |
7727 | 7889 | |
| 7890 | + // Serialize the markers array to a string and compare it with the one stored in the previous run |
| 7891 | + // If they're equal, there's no markers to change |
| 7892 | + var markersStr = ''; |
| 7893 | + for ( var i = 0; i < markers.length; i++ ) { |
| 7894 | + markersStr += markers[i].start + ',' + markers[i].end + ',' + markers[i].type + ','; |
| 7895 | + } |
| 7896 | + if ( context.modules.highlight.markersStr == markersStr ) { |
| 7897 | + // No change, bail out |
| 7898 | + return; |
| 7899 | + } |
| 7900 | + context.modules.highlight.markersStr = markersStr; |
| 7901 | + |
7728 | 7902 | // Traverse the iframe DOM, inserting markers where they're needed. |
| 7903 | + // Store visited markers here so we know which markers should be removed |
| 7904 | + var visited = []; |
7729 | 7905 | for ( var i = 0; i < markers.length; i++ ) { |
7730 | 7906 | // We want to isolate each marker, so we may need to split textNodes |
7731 | 7907 | // if a marker starts or ends halfway one. |
— | — | @@ -7736,23 +7912,27 @@ |
7737 | 7913 | } |
7738 | 7914 | var startNode = s.node; |
7739 | 7915 | var startDepth = s.depth; |
7740 | | - // The next marker starts somewhere in this textNode or at this BR |
7741 | | - if ( s.offset > 0 ) { |
7742 | | - // t.node must be a textnode at this point because |
7743 | | - // only textnodes can have offset > 0 |
7744 | | - |
7745 | | - // Split off the prefix |
7746 | | - // This leaves the prefix in the current node and puts |
7747 | | - // the rest in a new node which is our start node |
7748 | | - startNode = startNode.splitText( s.offset ); |
7749 | | - } |
| 7916 | + |
7750 | 7917 | // Don't wrap leading BRs, produces undesirable results |
7751 | | - while ( startNode.nodeName == 'BR' ) { |
| 7918 | + // FIXME: It's also possible that the offset is a bit high because getOffset() has incremented |
| 7919 | + // .length to fake the newline caused by startNode being in a P. In this case, prevent |
| 7920 | + // the textnode splitting below from making startNode an empty textnode, IE barfs on that |
| 7921 | + while ( startNode.nodeName == 'BR' || s.offset == startNode.nodeValue.length ) { |
7752 | 7922 | start++; |
7753 | 7923 | s = context.fn.getOffset( start ); |
7754 | 7924 | startNode = s.node; |
7755 | 7925 | startDepth = s.depth; |
7756 | 7926 | } |
| 7927 | + |
| 7928 | + // The next marker starts somewhere in this textNode or at this BR |
| 7929 | + if ( s.offset > 0 && s.node.nodeName == '#text' ) { |
| 7930 | + // Split off the prefix |
| 7931 | + // This leaves the prefix in the current node and puts |
| 7932 | + // the rest in a new node which is our start node |
| 7933 | + startNode = startNode.splitText( s.offset ); |
| 7934 | + // This also invalidates cached offset objects |
| 7935 | + context.fn.purgeOffsets(); // TODO: Optimize better, get end offset object earlier |
| 7936 | + } |
7757 | 7937 | |
7758 | 7938 | var end = markers[i].end; |
7759 | 7939 | var e = context.fn.getOffset( end ); |
— | — | @@ -7762,14 +7942,13 @@ |
7763 | 7943 | } |
7764 | 7944 | var endNode = e.node; |
7765 | 7945 | var endDepth = e.depth; |
7766 | | - if ( e.offset < e.length - 1 ) { |
7767 | | - // t.node must be a textnode at this point because |
7768 | | - // .length is 1 for BRs and offset can't be < 0 |
7769 | | - |
| 7946 | + if ( e.offset < e.length - 1 && e.node.nodeName == '#text' ) { |
7770 | 7947 | // Split off the suffix - This puts the suffix in a new node and leaves the rest in the current |
7771 | 7948 | // node. |
7772 | 7949 | // endNode.nodeValue.length - ( newPos - markers[i].end ) |
7773 | 7950 | endNode.splitText( e.offset + 1 ); |
| 7951 | + // This also invalidates cached offset objects |
| 7952 | + context.fn.purgeOffsets(); // TODO: Optimize better, get end offset object earlier |
7774 | 7953 | } |
7775 | 7954 | |
7776 | 7955 | // Don't wrap trailing BRs, doing that causes weird issues |
— | — | @@ -7809,13 +7988,19 @@ |
7810 | 7989 | ca1 = ca1.parentNode.firstChild == ca1 ? ca1.parentNode : null; |
7811 | 7990 | ca2 = ca2.parentNode.lastChild == ca2 ? ca2.parentNode : null; |
7812 | 7991 | } |
7813 | | - if ( ca1 && ca2 && ca1.parentNode && ca2.nextSibling ) { |
| 7992 | + if ( ca1 && ca2 && ca1.parentNode ) { |
7814 | 7993 | var anchor = markers[i].getAnchor( ca1, ca2 ); |
7815 | 7994 | if ( !anchor ) { |
7816 | 7995 | // We have to store things like .parentNode and .nextSibling because appendChild() changes these |
7817 | 7996 | // properties |
7818 | 7997 | var newNode = ca1.ownerDocument.createElement( 'div' ); |
7819 | 7998 | var commonAncestor = ca1.parentNode; |
| 7999 | + // Special case: can't put block elements in a <p> |
| 8000 | + if ( commonAncestor.nodeName == 'P' && commonAncestor.parentNode ) { |
| 8001 | + commonAncestor = commonAncestor.parentNode; |
| 8002 | + ca1 = ca1.parentNode; |
| 8003 | + ca2 = ca2.parentNode; |
| 8004 | + } |
7820 | 8005 | var nextNode = ca2.nextSibling; |
7821 | 8006 | if ( markers[i].anchor == 'wrap' ) { |
7822 | 8007 | // Append all nodes between ca1 and ca2 (inclusive) to newNode |
— | — | @@ -7842,22 +8027,32 @@ |
7843 | 8028 | } |
7844 | 8029 | |
7845 | 8030 | $( newNode ).data( 'marker', markers[i] ) |
7846 | | - .addClass( 'wikiEditor-highlight wikiEditor-highlight-tmp' ); |
| 8031 | + .addClass( 'wikiEditor-highlight' ); |
| 8032 | + visited[i] = newNode; |
7847 | 8033 | |
7848 | 8034 | // Allow the module adding this marker to manipulate it |
7849 | 8035 | markers[i].afterWrap( newNode, markers[i] ); |
7850 | 8036 | } else { |
7851 | | - // Temporarily add a class for bookkeeping purposes |
7852 | | - $( anchor ) |
7853 | | - .addClass( 'wikiEditor-highlight-tmp' ) |
7854 | | - .data( 'marker', markers[i] ); |
| 8037 | + visited[i] = anchor; |
| 8038 | + // Update the marker object |
| 8039 | + $( anchor ).data( 'marker', markers[i] ); |
7855 | 8040 | markers[i].onSkip( anchor ); |
7856 | 8041 | } |
7857 | 8042 | } |
7858 | 8043 | } |
7859 | 8044 | |
7860 | 8045 | // Remove markers that were previously inserted but weren't passed to this function |
7861 | | - context.$content.find( 'div.wikiEditor-highlight:not(.wikiEditor-highlight-tmp)' ).each( function() { |
| 8046 | + // This function works because visited[] contains the visited elements in order and find() and each() |
| 8047 | + // preserve order |
| 8048 | + var j = 0; |
| 8049 | + context.$content.find( 'div.wikiEditor-highlight' ).each( function() { |
| 8050 | + if ( visited[j] == this ) { |
| 8051 | + // This marker is legit, leave it in |
| 8052 | + j++; |
| 8053 | + return true; |
| 8054 | + } |
| 8055 | + |
| 8056 | + // Remove this marker |
7862 | 8057 | if ( $(this).data( 'marker' ) && typeof $(this).data( 'marker' ).unwrap == 'function' ) |
7863 | 8058 | $(this).data( 'marker' ).unwrap( this ); |
7864 | 8059 | if ( $(this).children().size() > 0 ) { |
— | — | @@ -7866,8 +8061,6 @@ |
7867 | 8062 | $(this).replaceWith( $(this).html() ); |
7868 | 8063 | } |
7869 | 8064 | }); |
7870 | | - // Remove temporary class |
7871 | | - context.$content.find( 'div.wikiEditor-highlight-tmp' ).removeClass( 'wikiEditor-highlight-tmp' ); |
7872 | 8065 | } |
7873 | 8066 | } |
7874 | 8067 | |
— | — | @@ -8172,6 +8365,7 @@ |
8173 | 8366 | markers.push( { |
8174 | 8367 | start: tokenArray[beginIndex].offset, |
8175 | 8368 | end: tokenArray[endIndex].offset, |
| 8369 | + type: 'template', |
8176 | 8370 | anchor: 'wrap', |
8177 | 8371 | afterWrap: $.wikiEditor.modules.templateEditor.fn.stylize, |
8178 | 8372 | beforeUnwrap: function( node ) { |
— | — | @@ -8822,6 +9016,7 @@ |
8823 | 9017 | context.modules.toc.$toc.data( 'previousWidth', context.$wikitext.width() ); |
8824 | 9018 | }, |
8825 | 9019 | mark: function( context, event ) { |
| 9020 | + var hash = ''; |
8826 | 9021 | var markers = context.modules.highlight.markers; |
8827 | 9022 | var tokenArray = context.modules.highlight.tokenArray; |
8828 | 9023 | var outline = context.data.outline = []; |
— | — | @@ -8835,6 +9030,7 @@ |
8836 | 9031 | index: h, |
8837 | 9032 | start: tokenArray[i].tokenStart, |
8838 | 9033 | end: tokenArray[i].offset, |
| 9034 | + type: 'toc', |
8839 | 9035 | anchor: 'before', |
8840 | 9036 | afterWrap: function( node ) { |
8841 | 9037 | var marker = $( node ).data( 'marker' ); |
— | — | @@ -8844,24 +9040,32 @@ |
8845 | 9041 | }, |
8846 | 9042 | onSkip: function( node ) { |
8847 | 9043 | var marker = $( node ).data( 'marker' ); |
8848 | | - $( node ) |
8849 | | - .removeClass( 'wikiEditor-toc-section-' + $( node ).data( 'section' ) ) |
8850 | | - .addClass( 'wikiEditor-toc-section-' + marker.index ) |
8851 | | - .data( 'section', marker.index ); |
| 9044 | + if ( $( node ).data( 'section' ) != marker.index ) { |
| 9045 | + $( node ) |
| 9046 | + .removeClass( 'wikiEditor-toc-section-' + $( node ).data( 'section' ) ) |
| 9047 | + .addClass( 'wikiEditor-toc-section-' + marker.index ) |
| 9048 | + .data( 'section', marker.index ); |
| 9049 | + } |
8852 | 9050 | }, |
8853 | 9051 | getAnchor: function( ca1, ca2 ) { |
8854 | | - return $( ca1.previousSibling ).is( 'div.wikiEditor-toc-header' ) ? |
8855 | | - ca1.previousSibling : null; |
| 9052 | + return $( ca1.parentNode.previousSibling ).is( 'div.wikiEditor-toc-header' ) ? |
| 9053 | + ca1.parentNode.previousSibling : null; |
8856 | 9054 | } |
8857 | 9055 | } ); |
| 9056 | + hash += tokenArray[i].match[2] + '\n'; |
8858 | 9057 | outline.push ( { |
8859 | 9058 | 'text': tokenArray[i].match[2], |
8860 | 9059 | 'level': tokenArray[i].match[1].length, |
8861 | 9060 | 'index': h |
8862 | 9061 | } ); |
8863 | 9062 | } |
8864 | | - $.wikiEditor.modules.toc.fn.build( context ); |
8865 | | - $.wikiEditor.modules.toc.fn.update( context ); |
| 9063 | + // Only update the TOC if it's been changed - we do this by comparing a hash of the headings this time to last |
| 9064 | + if ( typeof context.modules.toc.lastHash == 'undefined' || context.modules.toc.lastHash !== hash ) { |
| 9065 | + $.wikiEditor.modules.toc.fn.build( context ); |
| 9066 | + $.wikiEditor.modules.toc.fn.update( context ); |
| 9067 | + // Remember the changed version |
| 9068 | + context.modules.toc.lastHash = hash; |
| 9069 | + } |
8866 | 9070 | } |
8867 | 9071 | }, |
8868 | 9072 | exp: [ |
— | — | @@ -8998,7 +9202,7 @@ |
8999 | 9203 | update: function( context ) { |
9000 | 9204 | $.wikiEditor.modules.toc.fn.unhighlight( context ); |
9001 | 9205 | |
9002 | | - var div = context.fn.beforeSelection( 'div.wikiEditor-toc-header' ); |
| 9206 | + var div = context.fn.beforeSelection( 'wikiEditor-toc-header' ); |
9003 | 9207 | var section = div.data( 'section' ) || 0; |
9004 | 9208 | if ( context.data.outline.length > 0 ) { |
9005 | 9209 | var sectionLink = context.modules.toc.$toc.find( 'div.section-' + section ); |
— | — | @@ -9132,17 +9336,18 @@ |
9133 | 9337 | function buildList( structure ) { |
9134 | 9338 | var list = $( '<ul />' ); |
9135 | 9339 | for ( i in structure ) { |
9136 | | - var wrapper = context.$content.find( '.wikiEditor-toc-section-' + structure[i].index ); |
9137 | | - if ( wrapper.size() == 0 ) |
9138 | | - wrapper = context.$content; |
9139 | 9340 | var div = $( '<div />' ) |
9140 | 9341 | .addClass( 'section-' + structure[i].index ) |
9141 | | - .data( 'wrapper', wrapper ) |
| 9342 | + .data( 'index', structure[i].index ) |
9142 | 9343 | .click( function( event ) { |
9143 | | - context.fn.scrollToTop( $( this ).data( 'wrapper' ), true ); |
| 9344 | + var wrapper = context.$content.find( |
| 9345 | + '.wikiEditor-toc-section-' + $( this ).data( 'index' ) ); |
| 9346 | + if ( wrapper.size() == 0 ) |
| 9347 | + wrapper = context.$content; |
| 9348 | + context.fn.scrollToTop( wrapper, true ); |
9144 | 9349 | context.$textarea.textSelection( 'setSelection', { |
9145 | 9350 | 'start': 0, |
9146 | | - 'startContainer': $(this).data( 'wrapper' ) |
| 9351 | + 'startContainer': wrapper |
9147 | 9352 | } ); |
9148 | 9353 | // Highlight the clicked link |
9149 | 9354 | $.wikiEditor.modules.toc.fn.unhighlight( context ); |
— | — | @@ -9237,7 +9442,9 @@ |
9238 | 9443 | if( ui.size.width <= parseFloat( $.wikiEditor.modules.toc.cfg.minimumWidth ) ) { |
9239 | 9444 | context.modules.toc.$toc.trigger( 'collapse.wikiEditor-toc' ); |
9240 | 9445 | } else { |
9241 | | - context.modules.toc.$toc.find( 'div' ).autoEllipsis( { 'position': 'right', 'tooltip': true, 'restoreText': true } ); |
| 9446 | + context.modules.toc.$toc.find( 'div' ).autoEllipsis( |
| 9447 | + { 'position': 'right', 'tooltip': true, 'restoreText': true } |
| 9448 | + ); |
9242 | 9449 | context.modules.toc.$toc.data( 'openWidth', ui.size.width ); |
9243 | 9450 | $.cookie( 'wikiEditor-' + context.instance + '-toc-width', ui.size.width ); |
9244 | 9451 | } |
— | — | @@ -9301,7 +9508,9 @@ |
9302 | 9509 | buildResizeControls(); |
9303 | 9510 | buildCollapseControls(); |
9304 | 9511 | } |
9305 | | - context.modules.toc.$toc.find( 'div' ).autoEllipsis( { 'position': 'right', 'tooltip': true, 'restoreText': true } ); |
| 9512 | + context.modules.toc.$toc.find( 'div' ).autoEllipsis( |
| 9513 | + { 'position': 'right', 'tooltip': true, 'restoreText': true } |
| 9514 | + ); |
9306 | 9515 | } |
9307 | 9516 | } |
9308 | 9517 | } |
— | — | @@ -9429,7 +9638,7 @@ |
9430 | 9639 | $( $.wikiEditor.modules.toolbar.fn.buildCharacter( data[type][character], actions ) ) |
9431 | 9640 | .click( function() { |
9432 | 9641 | $.wikiEditor.modules.toolbar.fn.doAction( $(this).parent().data( 'context' ), |
9433 | | - $(this).parent().data( 'actions' )[$(this).attr( 'rel' )] ); |
| 9642 | + $(this).parent().data( 'actions' )[$(this).attr( 'rel' )] ); |
9434 | 9643 | return false; |
9435 | 9644 | } ) |
9436 | 9645 | ); |
— | — | @@ -9525,7 +9734,7 @@ |
9526 | 9735 | doAction : function( context, action, source ) { |
9527 | 9736 | // Verify that this has been called from a source that's within the toolbar |
9528 | 9737 | // 'trackAction' defined in click tracking |
9529 | | - if ($.trackAction != undefined && source.closest( '.wikiEditor-ui-toolbar' ).size() ) { |
| 9738 | + if ( $.trackAction != undefined && source.closest( '.wikiEditor-ui-toolbar' ).size() ) { |
9530 | 9739 | // Build a unique id for this action by tracking the parent rel attributes up to the toolbar level |
9531 | 9740 | var rels = []; |
9532 | 9741 | var step = source; |
— | — | @@ -9543,7 +9752,7 @@ |
9544 | 9753 | } |
9545 | 9754 | rels.reverse(); |
9546 | 9755 | var id = rels.join( '.' ); |
9547 | | - $.trackAction(id); |
| 9756 | + $.trackAction( id ); |
9548 | 9757 | } |
9549 | 9758 | switch ( action.type ) { |
9550 | 9759 | case 'replace': |
— | — | @@ -9569,6 +9778,7 @@ |
9570 | 9779 | 'encapsulateSelection', |
9571 | 9780 | $.extend( {}, action.options, parts, { 'replace': action.type == 'replace' } ) |
9572 | 9781 | ); |
| 9782 | + context.$iframe[0].contentWindow.focus(); |
9573 | 9783 | break; |
9574 | 9784 | case 'callback': |
9575 | 9785 | if ( typeof action.execute == 'function' ) { |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/js/plugins.combined.min.js |
— | — | @@ -436,31 +436,39 @@ |
437 | 437 | options.endContainer=options.startContainer;break;case'scrollToCaretPosition':options=$.extend({'force':false},options);break;} |
438 | 438 | var context=$(this).data('wikiEditor-context');var hasIframe=context!==undefined&&context.$iframe!==undefined;return(hasIframe?context.fn:fn)[command].call(this,options);};})(jQuery);(function($){$.wikiEditor={'modules':{},'instances':[],'browsers':{'ltr':{'msie':[['>=',7]],'firefox':[['>=',2],['!=','2.0'],['!=','2.0.0.1'],['!=','2.0.0.2'],['!=','2.0.0.3'],['!=','2.0.0.4']],'opera':[['>=',9.6]],'safari':[['>=',3.1]]},'rtl':{'msie':[['>=',8]],'firefox':[['>=',2],['!=','2.0'],['!=','2.0.0.1'],['!=','2.0.0.2'],['!=','2.0.0.3'],['!=','2.0.0.4']],'opera':[['>=',9.6]],'safari':[['>=',3.1]]}},'imgPath':wgScriptPath+'/extensions/UsabilityInitiative_alpha/images/wikiEditor/','isSupported':function(){if(typeof $.wikiEditor.supported!='undefined'){return $.wikiEditor.supported;} |
439 | 439 | if(!($.browser.name in $.wikiEditor.browsers[$('body').is('.rtl')?'rtl':'ltr'])){return $.wikiEditor.supported=true;} |
440 | | -var browser=$.wikiEditor.browsers[$('body').is('.rtl')?'rtl':'ltr'][$.browser.name];for(condition in browser){var op=browser[condition][0];var val=browser[condition][1];if(typeof val=='string'){if(!(eval('$.browser.version'+op+'"'+val+'"'))){return $.wikiEditor.supported=false;}}else if(typeof val=='number'){if(!(eval('$.browser.versionNumber'+op+val))){return $.wikiEditor.supported=false;}}} |
441 | | -return $.wikiEditor.supported=true;},'autoMsg':function(object,property){if(typeof property=='object'){for(i in property){if(property[i]in object||property[i]+'Msg'in object){property=property[i];break;}}} |
| 440 | +var browser=$.wikiEditor.browsers[$('body').is('.rtl')?'rtl':'ltr'][$.browser.name];for(var condition in browser){var op=browser[condition][0];var val=browser[condition][1];if(typeof val=='string'){if(!(eval('$.browser.version'+op+'"'+val+'"'))){return $.wikiEditor.supported=false;}}else if(typeof val=='number'){if(!(eval('$.browser.versionNumber'+op+val))){return $.wikiEditor.supported=false;}}} |
| 441 | +return $.wikiEditor.supported=true;},'autoMsg':function(object,property){if(typeof property=='object'){for(var i in property){if(property[i]in object||property[i]+'Msg'in object){property=property[i];break;}}} |
442 | 442 | if(property in object){return object[property];}else if(property+'Msg'in object){if(typeof object[property+'Msg']=='object'){return mw.usability.getMsg.apply(mw.usability,object[property+'Msg']);}else{return mw.usability.getMsg(object[property+'Msg']);}}else{return'';}},'autoLang':function(object,lang){return object[lang||wgUserLanguage]||object['default']||object;},'autoIcon':function(icon,path,lang){var src=$.wikiEditor.autoLang(icon,lang);path=path||$.wikiEditor.imgPath;if(src.substr(0,7)!='http://'&&src.substr(0,8)!='https://'&&src[0]!='/'){src=path+src;} |
443 | 443 | return src+'?'+wgWikiEditorIconVersion;}};$.fn.wikiEditor=function(){if(!$j.wikiEditor.isSupported()){return $(this);} |
444 | | -var context=$(this).data('wikiEditor-context');if(typeof context=='undefined'){context={'$textarea':$(this),'views':{},'modules':{},'data':{},'instance':$.wikiEditor.instances.push($(this))-1,'offsets':null};context.api={'addModule':function(context,data){var modules={};if(typeof data=='string'){modules[data]={};}else if(typeof data=='object'){modules=data;} |
445 | | -for(module in modules){if(typeof module=='string'&&module in $.wikiEditor.modules){if('api'in $.wikiEditor.modules[module]){for(call in $.wikiEditor.modules[module].api){if(!(call in context.api)){context.api[call]=$.wikiEditor.modules[module].api[call];}}} |
446 | | -if('fn'in $.wikiEditor.modules[module]&&'create'in $.wikiEditor.modules[module].fn){context.modules[module]={};$.wikiEditor.modules[module].fn.create(context,modules[module]);}}}}};context.evt={'change':function(event){event.data.scope='division';context.fn.purgeOffsets();return true;},'delayedChange':function(event){return context.evt.change(event);}};context.fn={'trigger':function(name,event){if(typeof event=='undefined'){event={'type':'custom'};} |
| 444 | +var context=$(this).data('wikiEditor-context');if(typeof context=='undefined'){context={'$textarea':$(this),'views':{},'modules':{},'data':{},'instance':$.wikiEditor.instances.push($(this))-1,'offsets':null,'htmlToTextMap':{},'oldHTML':null,'oldDelayedHTML':null};context.api={'addModule':function(context,data){var modules={};if(typeof data=='string'){modules[data]={};}else if(typeof data=='object'){modules=data;} |
| 445 | +for(var module in modules){if(typeof module=='string'&&module in $.wikiEditor.modules){if('api'in $.wikiEditor.modules[module]){for(var call in $.wikiEditor.modules[module].api){if(!(call in context.api)){context.api[call]=$.wikiEditor.modules[module].api[call];}}} |
| 446 | +if('fn'in $.wikiEditor.modules[module]&&'create'in $.wikiEditor.modules[module].fn){context.modules[module]={};$.wikiEditor.modules[module].fn.create(context,modules[module]);}}}}};context.evt={'change':function(event){event.data.scope='division';var newHTML=context.$content.html();if(context.oldHTML!=newHTML){context.fn.purgeOffsets();context.oldHTML=newHTML;event.data.scope='realchange';} |
| 447 | +return true;},'delayedChange':function(event){event.data.scope='division';var newHTML=context.$content.html();if(context.oldDelayedHTML!=newHTML){context.fn.purgeOffsets();context.oldDelayedHTML=newHTML;event.data.scope='realchange';} |
| 448 | +return true;}};context.fn={'trigger':function(name,event){if(typeof event=='undefined'){event={'type':'custom'};} |
447 | 449 | if(typeof event.data=='undefined'){event.data={};} |
448 | 450 | if(name in context.evt){if(!context.evt[name](event)){return false;}} |
449 | | -for(module in context.modules){if(module in $.wikiEditor.modules&&'evt'in $.wikiEditor.modules[module]&&name in $.wikiEditor.modules[module].evt){$.wikiEditor.modules[module].evt[name](context,event);}}},'addButton':function(options){context.$controls.show();context.$buttons.show();return $('<button />').text($.wikiEditor.autoMsg(options,'caption')).click(options.action).appendTo(context.$buttons);},'addView':function(options){function addTab(options){context.$controls.show();context.$tabs.show();return $('<div></div>').attr('rel','wikiEditor-ui-view-'+options.name).addClass(context.view==options.name?'current':null).append($('<a></a>').attr('href','#').click(function(event){context.$ui.find('.wikiEditor-ui-view').hide();context.$ui.find('.'+$(this).parent().attr('rel')).show();context.$tabs.find('div').removeClass('current');$(this).parent().addClass('current');$(this).blur();if('init'in options&&typeof options.init=='function'){options.init(context);} |
| 451 | +for(var module in context.modules){if(module in $.wikiEditor.modules&&'evt'in $.wikiEditor.modules[module]&&name in $.wikiEditor.modules[module].evt){$.wikiEditor.modules[module].evt[name](context,event);}}},'addButton':function(options){context.$controls.show();context.$buttons.show();return $('<button />').text($.wikiEditor.autoMsg(options,'caption')).click(options.action).appendTo(context.$buttons);},'addView':function(options){function addTab(options){context.$controls.show();context.$tabs.show();return $('<div></div>').attr('rel','wikiEditor-ui-view-'+options.name).addClass(context.view==options.name?'current':null).append($('<a></a>').attr('href','#').click(function(event){context.$ui.find('.wikiEditor-ui-view').hide();context.$ui.find('.'+$(this).parent().attr('rel')).show();context.$tabs.find('div').removeClass('current');$(this).parent().addClass('current');$(this).blur();if('init'in options&&typeof options.init=='function'){options.init(context);} |
450 | 452 | event.preventDefault();return false;}).text($.wikiEditor.autoMsg(options,'title'))).appendTo(context.$tabs);} |
451 | 453 | if(!context.$tabs.children().size()){addTab({'name':'wikitext','titleMsg':'wikieditor-wikitext-tab'});} |
452 | | -addTab(options);return $('<div></div>').addClass('wikiEditor-ui-view wikiEditor-ui-view-'+options.name).hide().appendTo(context.$ui);},'htmlToText':function(html){var $pre=$('<pre>'+ |
453 | | -html.replace(/\r?\n/g,"").replace(/\<br[^\>]*\>/gi,"\n").replace(/ /g," ").replace(/\<p[^\>]*\>/gi,"\n").replace(/\<\/p[^\>]*\>/gi,"").replace(/\<div[^\>]*\>/gi,"\n").replace(/\<\/div[^\>]*\>/gi,"") |
454 | | -+'</pre>');$pre.find('.wikiEditor-noinclude').each(function(){$(this).remove();});$pre.find('.wikiEditor-tab').each(function(){$(this).text("\t")});return $pre.text();},'getContents':function(){return context.fn.htmlToText(context.$content.html());},'getSelection':function(){var retval;if(context.$iframe[0].contentWindow.getSelection){retval=context.$iframe[0].contentWindow.getSelection();}else if(context.$iframe[0].contentWindow.document.selection){retval=context.$iframe[0].contentWindow.document.selection.createRange();} |
| 454 | +addTab(options);return $('<div></div>').addClass('wikiEditor-ui-view wikiEditor-ui-view-'+options.name).hide().appendTo(context.$ui);},'htmlToText':function(html){if(html in context.htmlToTextMap){return context.htmlToTextMap[html];} |
| 455 | +var origHTML=html;html=html.replace(/\r?\n/g,"").replace(/ /g," ").replace(/\<br[^\>]*\>/gi,"\n").replace(/\<\/p\>\<p\>/gi,"\n").replace(/\<\/p\>(\n*)\<p\>/gi,"$1\n");var leading=html.match(/^\s*/)[0];var trailing=html.match(/\s*$/)[0];html=html.substr(leading.length,html.length-leading.length-trailing.length);var $pre=$('<pre>'+html+'</pre>');$pre.find('.wikiEditor-noinclude').each(function(){$(this).remove();});$pre.find('.wikiEditor-tab').each(function(){$(this).text("\t");});$pre.find('br').each(function(){$(this).replaceWith("\n");});$pre.find('p').each(function(){if(this.previousSibling||this.parentNode!=$pre.get(0)){var text=$(this).text();var t=new context.fn.rawTraverser(this.firstChild,-10,this).prev();while(t&&t.node.nodeName!='#text'&&t.node.nodeName!='BR'&&t.node.nodeName!='P'){t=t.prev();} |
| 456 | +if(t){text="\n"+text;} |
| 457 | +t=new context.fn.rawTraverser(this.lastChild,-10,this).next();while(t&&t.node.nodeName!='#text'&&t.node.nodeName!='BR'&&t.node.nodeName!='P'){t=t.next();} |
| 458 | +if(t&&!t.inP&&t.node.nodeName=='#text'&&t.node.nodeValue.charAt(0)!='\n'&&t.node.nodeValue.charAt(0)!='\r'){text+="\n";} |
| 459 | +$(this).text(text);}});var retval;if($.browser.msie){retval=$('<pre>'+$pre.html()+'</pre>').text().replace(/\r/g,'\n');}else{retval=$pre.text();} |
| 460 | +return context.htmlToTextMap[origHTML]=leading+retval+trailing;},'getContents':function(){return context.fn.htmlToText(context.$content.html());},'getSelection':function(){var retval;if(context.$iframe[0].contentWindow.getSelection){retval=context.$iframe[0].contentWindow.getSelection();if($.browser.opera){if(retval.rangeCount>0){retval=context.fn.htmlToText($('<pre />').append(retval.getRangeAt(0).cloneContents()).html());}else{retval='';}}}else if(context.$iframe[0].contentWindow.document.selection){retval=context.$iframe[0].contentWindow.document.selection.createRange();} |
455 | 461 | if(typeof retval.text!='undefined'){retval=context.fn.htmlToText(retval.htmlText);}else if(retval.toString){retval=retval.toString();} |
456 | 462 | return retval;},'encapsulateSelection':function(options){var selText=$(this).textSelection('getSelection');var selTextArr;var selectAfter=false;var pre=options.pre,post=options.post;if(!selText){selText=options.peri;selectAfter=true;}else if(options.replace){selText=options.peri;}else if(selText.charAt(selText.length-1)==' '){selText=selText.substring(0,selText.length-1);post+=' ';} |
457 | 463 | if(options.splitlines){selTextArr=selText.split(/\n/);} |
458 | | -if(context.$iframe[0].contentWindow.getSelection){var range=context.$iframe[0].contentWindow.getSelection().getRangeAt(0);if(options.ownline){var body=context.$content.get(0);if(range.startOffset!=0&&range.startContainer!=body){pre="\n"+options.pre;} |
459 | | -if(range.endContainer!=body||range.endOffset==0){post+="\n";}} |
460 | | -var insertText="";if(options.splitlines){for(var i=0;i<selTextArr.length;i++){insertText=insertText+pre+selTextArr[i]+post;if(i!=selTextArr.length-1)insertText+="\n";}}else{insertText=pre+selText+post;} |
| 464 | +if(context.$iframe[0].contentWindow.getSelection){var range=context.$iframe[0].contentWindow.getSelection().getRangeAt(0);if(options.ownline){var atStart=false,atEnd=false;var body=context.$content.get(0);if(range.startOffset==0){atStart=true;}else if(range.startContainer==body){var n=body.firstChild;for(var i=0;i<range.startOffset-1&&n;i++){n=n.nextSibling;} |
| 465 | +if(n&&n.nodeName=='BR'){atStart=true;}else{atEnd=true;}}else if(range.startContainer.nodeName=='#text'&&range.startOffset==range.startContainer.nodeValue.length){atEnd=true;} |
| 466 | +if(!atStart){pre="\n"+options.pre;} |
| 467 | +if(!atEnd){post+="\n";}} |
| 468 | +var insertText="";if(options.splitlines){for(var j=0;j<selTextArr.length;j++){insertText=insertText+pre+selTextArr[j]+post;if(j!=selTextArr.length-1){insertText+="\n";}}}else{insertText=pre+selText+post;} |
461 | 469 | var insertLines=insertText.split("\n");range.extractContents();var lastNode;for(var i=insertLines.length-1;i>=0;i--){range.insertNode(context.$iframe[0].contentWindow.document.createTextNode(insertLines[i]));if(i>0){lastNode=range.insertNode(context.$iframe[0].contentWindow.document.createElement('br'));}} |
462 | 470 | if(lastNode){context.fn.scrollToTop(lastNode);}}else if(context.$iframe[0].contentWindow.document.selection){context.$iframe[0].contentWindow.focus();var range=context.$iframe[0].contentWindow.document.selection.createRange();if(options.ownline&&range.moveStart){var range2=context.$iframe[0].contentWindow.document.selection.createRange();range2.collapse();range2.moveStart('character',-1);if(range2.text!="\r"&&range2.text!="\n"&&range2.text!=""){pre="\n"+pre;} |
463 | 471 | var range3=context.$iframe[0].contentWindow.document.selection.createRange();range3.collapse(false);range3.moveEnd('character',1);if(range3.text!="\r"&&range3.text!="\n"&&range3.text!=""){post+="\n";}} |
464 | | -var insertText="";if(options.splitlines){for(var i=0;i<selTextArr.length;i++){insertText=insertText+pre+selTextArr[i]+post;if(i!=selTextArr.length-1){insertText+="\n";}}}else{insertText=pre+selText+post;} |
| 472 | +var insertText="";if(options.splitlines){for(var j=0;j<selTextArr.length;j++){insertText=insertText+pre+selTextArr[j]+post;if(j!=selTextArr.length-1){insertText+="\n";}}}else{insertText=pre+selText+post;} |
465 | 473 | range.pasteHTML(insertText.replace(/\</g,'<').replace(/>/g,'>').replace(/\r?\n/g,'<br />'));} |
466 | 474 | $(context.$iframe[0].contentWindow.document).trigger('encapsulateSelection',[pre,options.peri,post,options.ownline,options.replace]);return context.$textarea;},'getCaretPosition':function(options){},'setSelection':function(options){var sc=options.startContainer,ec=options.endContainer;sc=sc&&sc.jquery?sc[0]:sc;ec=ec&&ec.jquery?ec[0]:ec;if(context.$iframe[0].contentWindow.getSelection){var start=options.start,end=options.end;if(!sc||!ec){var s=context.fn.getOffset(start);var e=context.fn.getOffset(end);sc=s?s.node:null;ec=e?e.node:null;start=s?s.offset:null;end=e?e.offset:null;} |
467 | 475 | if(!sc||!ec){return context.$textarea;} |
— | — | @@ -471,57 +479,65 @@ |
472 | 480 | range2.collapse();range2.moveEnd('character',options.end);range.setEndPoint('EndToEnd',range2);range.select();} |
473 | 481 | return context.$textarea;},'scrollToCaretPosition':function(options){},'scrollToTop':function($element,force){var html=context.$content.closest('html'),body=context.$content.closest('body'),parentHtml=$('html'),parentBody=$('body');var y=$element.offset().top;if(!$.browser.msie&&!$element.is('body')){y=parentHtml.scrollTop()>0?y+html.scrollTop()-parentHtml.scrollTop():y;y=parentBody.scrollTop()>0?y+body.scrollTop()-parentBody.scrollTop():y;} |
474 | 482 | var topBound=html.scrollTop()>body.scrollTop()?html.scrollTop():body.scrollTop(),bottomBound=topBound+context.$iframe.height();if(force||y<topBound||y>bottomBound){html.scrollTop(y);body.scrollTop(y);} |
475 | | -$element.trigger('scrollToTop');},'beforeSelection':function(selector,strict){if(typeof selector=='undefined'){selector='*';} |
476 | | -var e,offset;if(context.$iframe[0].contentWindow.getSelection){var selection=context.$iframe[0].contentWindow.getSelection();if(selection.baseNode!==null){e=selection.getRangeAt(0).startContainer;offset=selection.startOffset;}else{return $([]);}}else if(context.$iframe[0].contentWindow.document.selection){var range=context.$iframe[0].contentWindow.document.selection.createRange();var range2=context.$iframe[0].contentWindow.document.body.createTextRange();try{range2.setEndPoint('EndToStart',range);}catch(e){return $([]);} |
| 483 | +$element.trigger('scrollToTop');},'beforeSelection':function(classname,strict){if(typeof classname=='undefined'){classname='';} |
| 484 | +var e,offset;if(context.$iframe[0].contentWindow.getSelection){var selection=context.$iframe[0].contentWindow.getSelection();if(selection.baseNode!==null){e=selection.getRangeAt(0).startContainer;offset=selection.getRangeAt(0).startOffset;}else{return $([]);}}else if(context.$iframe[0].contentWindow.document.selection){var range=context.$iframe[0].contentWindow.document.selection.createRange();var range2=context.$iframe[0].contentWindow.document.body.createTextRange();try{range2.setEndPoint('EndToStart',range);}catch(ex){return $([]);} |
477 | 485 | var seekPos=context.fn.htmlToText(range2.htmlText).length;var offset=context.fn.getOffset(seekPos);e=offset?offset.node:null;offset=offset?offset.offset:null;if(!e){return $([]);}} |
478 | 486 | if(e.nodeName!='#text'){var newE=e.firstChild;for(var i=0;i<offset-1&&newE;i++){newE=newE.nextSibling;} |
479 | 487 | while(newE&&newE.lastChild){newE=newE.lastChild;} |
480 | 488 | e=newE||e;} |
481 | | -while(e){if($(e).is(selector)&&!strict) |
482 | | -return $(e);var next=e.previousSibling;while(next&&next.lastChild){next=next.lastChild;} |
| 489 | +var classStr=' '+classname+' ';while(e){if(!strict&&(!classname||(' '+e.className+' ').indexOf(classStr)!=-1)){return $(e);} |
| 490 | +var next=e.previousSibling;while(next&&next.lastChild){next=next.lastChild;} |
483 | 491 | e=next||e.parentNode;strict=false;} |
484 | | -return $([]);},'traverser':function(start){function Traverser(node,depth,inP){this.node=node;this.depth=depth;this.inP=inP;this.next=function(){var p=this.node;var nextDepth=this.depth;var nextInP=this.inP;while(p&&!p.nextSibling){if(p.nodeName=="P"){nextInP=false;} |
485 | | -p=p.parentNode;nextDepth--;if(nextDepth==0){p=null;}} |
486 | | -p=p?p.nextSibling:null;do{while(p&&(' '+p.className+' ').indexOf(' wikiEditor-noinclude ')!=-1){p=p.nextSibling;} |
487 | | -if(p&&p.firstChild){p=p.firstChild;nextDepth++;if(p.nodeName=="P"){nextInP=true;}}}while(p&&p.firstChild);return p?new Traverser(p,nextDepth,nextInP):null;};} |
488 | | -var node=start.jquery?start.get(0):start;var depth=0;var inP=node.nodeName=="P";do{while(node&&(' '+node.className+' ').indexOf(' wikiEditor-noinclude ')!=-1){node=node.nextSibling;} |
489 | | -if(node&&node.firstChild){node=node.firstChild;depth++;if(node.nodeName=="P"){inP=true;}}}while(node&&node.firstChild);return new Traverser(node,depth,inP);},'getOffset':function(offset){if(!context.offsets){context.fn.refreshOffsets();} |
| 492 | +return $([]);},'rawTraverser':function(node,depth,inP){this.node=node;this.depth=depth;this.inP=inP;this.next=function(){var p=this.node;var nextDepth=this.depth;var nextInP=this.inP;while(p&&!p.nextSibling){p=p.parentNode;nextDepth--;if(nextDepth==0){p=null;} |
| 493 | +if(p&&p.nodeName=="P"){nextInP=null;}} |
| 494 | +p=p?p.nextSibling:null;if(p&&p.nodeName=="P"){nextInP=p;} |
| 495 | +do{while(p&&(' '+p.className+' ').indexOf(' wikiEditor-noinclude ')!=-1){p=p.nextSibling;} |
| 496 | +if(p&&p.firstChild){p=p.firstChild;nextDepth++;if(p.nodeName=="P"){nextInP=p;}}}while(p&&p.firstChild);return p?new context.fn.rawTraverser(p,nextDepth,nextInP):null;};this.prev=function(){var p=this.node;var prevDepth=this.depth;var prevInP=this.inP;while(p&&!p.previousSibling){p=p.parentNode;prevDepth--;if(prevDepth==0){p=null;} |
| 497 | +if(p&&p.nodeName=="P"){prevInP=null;}} |
| 498 | +p=p?p.previousSibling:null;if(p&&p.nodeName=="P"){prevInP=p;} |
| 499 | +do{while(p&&(' '+p.className+' ').indexOf(' wikiEditor-noinclude ')!=-1){p=p.previousSibling;} |
| 500 | +if(p&&p.lastChild){p=p.lastChild;prevDepth++;if(p.nodeName=="P"){prevInP=p;}}}while(p&&p.lastChild);return p?new context.fn.rawTraverser(p,prevDepth,prevInP):null;};},'traverser':function(start){var node=start.jquery?start.get(0):start;var depth=0;var inP=node.nodeName=="P"?node:null;do{while(node&&(' '+node.className+' ').indexOf(' wikiEditor-noinclude ')!=-1){node=node.nextSibling;} |
| 501 | +if(node&&node.firstChild){node=node.firstChild;depth++;if(node.nodeName=="P"){inP=node;}}}while(node&&node.firstChild);return new context.fn.rawTraverser(node,depth,inP);},'getOffset':function(offset){if(!context.offsets){context.fn.refreshOffsets();} |
490 | 502 | if(offset in context.offsets){return context.offsets[offset];} |
491 | 503 | var lowerBound=-1;for(var o in context.offsets){if(o>offset){break;} |
492 | 504 | lowerBound=o;} |
493 | 505 | if(!(lowerBound in context.offsets)){return null;} |
494 | | -var base=context.offsets[lowerBound];return context.offsets[offset]={'node':base.node,'offset':base.offset+offset-o,'length':base.length,'depth':base.depth,'lastTextNode':base.lastTextNode,'lastTextNodeDepth':base.lastTextNodeDepth};},'purgeOffsets':function(){context.offsets=null;},'refreshOffsets':function(){context.offsets=[];var t=context.fn.traverser(context.$content);var pos=0,lastTextNode=null,lastTextNodeDepth=null;while(t){if(t.node.nodeName!='#text'&&t.node.nodeName!='BR'){t=t.next();continue;} |
495 | | -var nextPos=t.node.nodeName=='#text'?pos+t.node.nodeValue.length:pos+1;var nextT=t.next();var leavingP=t.inP&&nextT&&!nextT.inP;context.offsets[pos]={'node':t.node,'offset':0,'length':nextPos-pos+(leavingP?1:0),'depth':t.depth,'lastTextNode':lastTextNode,'lastTextNodeDepth':lastTextNodeDepth};if(leavingP){context.offsets[nextPos]={'node':t.node,'offset':nextPos-pos,'length':nextPos-pos+1,'depth':t.depth,'lastTextNode':lastTextNode,'lastTextNodeDepth':lastTextNodeDepth};} |
| 506 | +var base=context.offsets[lowerBound];return context.offsets[offset]={'node':base.node,'offset':base.offset+offset-lowerBound,'length':base.length,'depth':base.depth,'lastTextNode':base.lastTextNode,'lastTextNodeDepth':base.lastTextNodeDepth};},'purgeOffsets':function(){context.offsets=null;},'refreshOffsets':function(){context.offsets=[];var t=context.fn.traverser(context.$content);var pos=0,lastTextNode=null,lastTextNodeDepth=null;while(t){if(t.node.nodeName!='#text'&&t.node.nodeName!='BR'&&t.node.nodeName!='P'){t=t.next();continue;} |
| 507 | +var nextPos=t.node.nodeName=='#text'?pos+t.node.nodeValue.length:pos+1;var nextT=t.next();var leavingP=t.node.nodeName!='P'&&t.inP&&nextT&&(!nextT.inP||nextT.inP!=t.inP);context.offsets[pos]={'node':t.node,'offset':0,'length':nextPos-pos+(leavingP?1:0),'depth':t.depth,'lastTextNode':lastTextNode,'lastTextNodeDepth':lastTextNodeDepth};if(leavingP){context.offsets[nextPos]={'node':t.node,'offset':nextPos-pos,'length':nextPos-pos+1,'depth':t.depth,'lastTextNode':lastTextNode,'lastTextNodeDepth':lastTextNodeDepth};} |
496 | 508 | pos=nextPos+(leavingP?1:0);if(t.node.nodeName=='#text'){lastTextNode=t.node;lastTextNodeDepth=t.depth;} |
497 | | -t=nextT;}}};context.$textarea.wrap($('<div></div>').addClass('wikiEditor-ui')).wrap($('<div></div>').addClass('wikiEditor-ui-view wikiEditor-ui-view-wikitext')).wrap($('<div></div>').addClass('wikiEditor-ui-left')).wrap($('<div></div>').addClass('wikiEditor-ui-bottom')).wrap($('<div></div>').addClass('wikiEditor-ui-text'));context.$ui=context.$textarea.parent().parent().parent().parent().parent();context.$wikitext=context.$textarea.parent().parent().parent().parent();context.$wikitext.before($('<div></div>').addClass('wikiEditor-ui-controls').append($('<div></div>').addClass('wikiEditor-ui-tabs').hide()).append($('<div></div>').addClass('wikiEditor-ui-buttons'))).before($('<div style="clear:both;"></div>'));context.$controls=context.$ui.find('.wikiEditor-ui-buttons').hide();context.$buttons=context.$ui.find('.wikiEditor-ui-buttons');context.$tabs=context.$ui.find('.wikiEditor-ui-tabs');context.$ui.after($('<div style="clear:both;"></div>'));context.$wikitext.append($('<div></div>').addClass('wikiEditor-ui-right'));context.$wikitext.find('.wikiEditor-ui-left').prepend($('<div></div>').addClass('wikiEditor-ui-top'));context.view='wikitext';$(window).resize(function(event){context.fn.trigger('resize',event)});context.$iframe=$('<iframe></iframe>').attr({'frameBorder':0,'border':0,'src':wgScriptPath+'/extensions/UsabilityInitiative_alpha/js/plugins/jquery.wikiEditor.html?'+'instance='+context.instance+'&ts='+(new Date()).getTime(),'id':'wikiEditor-iframe-'+context.instance}).css({'backgroundColor':'white','width':'100%','height':context.$textarea.height(),'display':'none','overflow-y':'scroll','overflow-x':'hidden'}).insertAfter(context.$textarea).load(function(){if(!this.isSecondRun){context.$iframe[0].contentWindow.document.designMode='on';if($.browser.msie){this.isSecondRun=true;return;}} |
498 | | -context.$content=$(context.$iframe[0].contentWindow.document.body);var html=context.$textarea.val();if($.browser.msie){if($.browser.versionNumber<=7){html=html.replace(/ /g," ");}else{html=html.replace(/(^|\n) /g,"$1 ");} |
| 509 | +t=nextT;}}};context.$textarea.wrap($('<div></div>').addClass('wikiEditor-ui')).wrap($('<div></div>').addClass('wikiEditor-ui-view wikiEditor-ui-view-wikitext')).wrap($('<div></div>').addClass('wikiEditor-ui-left')).wrap($('<div></div>').addClass('wikiEditor-ui-bottom')).wrap($('<div></div>').addClass('wikiEditor-ui-text'));context.$ui=context.$textarea.parent().parent().parent().parent().parent();context.$wikitext=context.$textarea.parent().parent().parent().parent();context.$wikitext.before($('<div></div>').addClass('wikiEditor-ui-controls').append($('<div></div>').addClass('wikiEditor-ui-tabs').hide()).append($('<div></div>').addClass('wikiEditor-ui-buttons'))).before($('<div style="clear:both;"></div>'));context.$controls=context.$ui.find('.wikiEditor-ui-buttons').hide();context.$buttons=context.$ui.find('.wikiEditor-ui-buttons');context.$tabs=context.$ui.find('.wikiEditor-ui-tabs');context.$ui.after($('<div style="clear:both;"></div>'));context.$wikitext.append($('<div></div>').addClass('wikiEditor-ui-right'));context.$wikitext.find('.wikiEditor-ui-left').prepend($('<div></div>').addClass('wikiEditor-ui-top'));context.view='wikitext';$(window).resize(function(event){context.fn.trigger('resize',event);});context.$iframe=$('<iframe></iframe>').attr({'frameBorder':0,'border':0,'src':wgScriptPath+'/extensions/UsabilityInitiative_alpha/js/plugins/jquery.wikiEditor.html?'+'instance='+context.instance+'&ts='+(new Date()).getTime(),'id':'wikiEditor-iframe-'+context.instance}).css({'backgroundColor':'white','width':'100%','height':context.$textarea.height(),'display':'none','overflow-y':'scroll','overflow-x':'hidden'}).insertAfter(context.$textarea).load(function(){if(!this.isSecondRun){context.$iframe[0].contentWindow.document.designMode='on';if($.browser.msie){this.isSecondRun=true;return;}} |
| 510 | +context.$content=$(context.$iframe[0].contentWindow.document.body);var html=context.$textarea.val().replace(/ /g,'&nbsp;').replace(/\<br\>/g,'<br>').replace(/\<span class="wikiEditor-tab"\>\<\/span\>/g,'<span class="wikiEditor-tab"></span>');if($.browser.msie){if($.browser.versionNumber<=7){html=html.replace(/ /g," ");}else{html=html.replace(/(^|\n) /g,"$1 ");} |
499 | 511 | html=html.replace(/\t/g,'<span class="wikiEditor-tab"></span>');} |
500 | | -html=$('<div />').text(html.replace(/\r?\n/g,'<br>')).html().replace(/&nbsp;/g,' ').replace(/<br>/g,'<br>').replace(/<span class="wikiEditor-tab"><\/span>/g,'<span class="wikiEditor-tab"></span>');context.$content.html(html);if($('body').is('.rtl')){context.$content.addClass('rtl').attr('dir','rtl');} |
501 | | -context.$textarea.attr('disabled',true);context.$textarea.hide();context.$iframe.show();context.fn.trigger('ready');$(context.$iframe[0].contentWindow.document).bind('keyup mouseup paste cut encapsulateSelection',function(event){context.fn.trigger('change',event);}).delayedBind(250,'keyup mouseup paste cut encapsulateSelection',function(event){context.fn.trigger('delayedChange',event);});});context.$textarea.closest('form').submit(function(){context.$textarea.attr('disabled',false);context.$textarea.val(context.$textarea.textSelection('getContents'));});context.fallbackWindowOnBeforeUnload=window.onbeforeunload;window.onbeforeunload=function(){context.$textarea.val(context.$textarea.textSelection('getContents'));return context.fallbackWindowOnBeforeUnload?context.fallbackWindowOnBeforeUnload():null;}} |
502 | | -arguments=$.makeArray(arguments);if(arguments.length>0){var call=arguments.shift();if(call in context.api){context.api[call](context,typeof arguments[0]=='undefined'?{}:arguments[0]);}} |
| 512 | +html=$('<div />').text('<p>'+html.replace(/\r?\n/g,'</p><p>')+'</p>').html().replace(/&nbsp;/g,' ').replace(/<p>/g,'<p>').replace(/<\/p>/g,'</p>').replace(/<p><\/p>/g,'<br>').replace(/<span class="wikiEditor-tab"><\/span>/g,'<span class="wikiEditor-tab"></span>').replace(/&amp;nbsp;/g,'&nbsp;').replace(/&lt;br&gt;/g,'<br>').replace(/&lt;span class=&quot;wikiEditor-tab&quot;&gt;&lt;\/span&gt;/g,'<span class="wikiEditor-tab"></span>');context.$content.html(html);context.oldHTML=html;if($('body').is('.rtl')){context.$content.addClass('rtl').attr('dir','rtl');} |
| 513 | +context.$textarea.attr('disabled',true);context.$textarea.hide();context.$iframe.show();context.fn.trigger('ready');$(context.$iframe[0].contentWindow.document).bind('keyup mouseup paste cut encapsulateSelection',function(event){context.fn.trigger('change',event);}).delayedBind(250,'keyup mouseup paste cut encapsulateSelection',function(event){context.fn.trigger('delayedChange',event);});});context.$textarea.closest('form').submit(function(){context.$textarea.attr('disabled',false);context.$textarea.val(context.$textarea.textSelection('getContents'));});context.fallbackWindowOnBeforeUnload=window.onbeforeunload;window.onbeforeunload=function(){context.$textarea.val(context.$textarea.textSelection('getContents'));return context.fallbackWindowOnBeforeUnload?context.fallbackWindowOnBeforeUnload():null;};} |
| 514 | +var args=$.makeArray(arguments);if(args.length>0){var call=args.shift();if(call in context.api){context.api[call](context,typeof args[0]=='undefined'?{}:args[0]);}} |
503 | 515 | return $(this).data('wikiEditor-context',context);};})(jQuery);RegExp.escape=function(s){return s.replace(/([.*+?^${}()|\/\\[\]])/g,'\\$1');};(function($){$.wikiEditor.modules.dialogs={api:{addDialog:function(context,data){$.wikiEditor.modules.dialogs.fn.create(context,data)},openDialog:function(context,module){if(module in $.wikiEditor.modules.dialogs.modules){$('#'+$.wikiEditor.modules.dialogs.modules[module].id).dialog('open');}},closeDialog:function(context,data){if(module in $.wikiEditor.modules.dialogs.modules){$('#'+$.wikiEditor.modules.dialogs.modules[module].id).dialog('close');}}},fn:{create:function(context,config){for(module in config){$.wikiEditor.modules.dialogs.modules[module]=config[module];} |
504 | 516 | mw.usability.load(['$j.ui','$j.ui.dialog','$j.ui.draggable','$j.ui.resizable'],function(){for(module in $.wikiEditor.modules.dialogs.modules){var module=$.wikiEditor.modules.dialogs.modules[module];if($('#'+module.id).size()==0){var configuration=module.dialog;configuration.bgiframe=true;configuration.autoOpen=false;configuration.modal=true;configuration.title=$.wikiEditor.autoMsg(module,'title');configuration.newButtons={};for(msg in configuration.buttons) |
505 | 517 | configuration.newButtons[mw.usability.getMsg(msg)]=configuration.buttons[msg];configuration.buttons=configuration.newButtons;var dialogDiv=$('<div /> ').attr('id',module.id).html(module.html).data('context',context).appendTo($('body')).each(module.init).dialog(configuration);if(!('resizeme'in module)||module.resizeme){dialogDiv.bind('dialogopen',$.wikiEditor.modules.dialogs.fn.resize).find('.ui-tabs').bind('tabsshow',function(){$(this).closest('.ui-dialog-content').each($.wikiEditor.modules.dialogs.fn.resize);});} |
506 | 518 | var maxTI=0;$j('[tabindex]').each(function(){var ti=parseInt($j(this).attr('tabindex'));if(ti>maxTI) |
507 | 519 | maxTI=ti;});var tabIndex=maxTI+1;$j('.ui-dialog input, .ui-dialog button').not('[tabindex]').each(function(){$j(this).attr('tabindex',tabIndex++);});}}});},resize:function(){var wrapper=$(this).closest('.ui-dialog');var oldWidth=wrapper.width();var oldHidden=$(this).find('*').not(':visible');oldHidden.each(function(){$(this).data('oldstyle',$(this).attr('style'));});oldHidden.show();var oldWS=$(this).css('white-space');$(this).css('white-space','nowrap');if(wrapper.width()<=$(this).get(0).scrollWidth){var thisWidth=$(this).data('thisWidth')?$(this).data('thisWidth'):0;thisWidth=Math.max($(this).get(0).scrollWidth,thisWidth);$(this).width(thisWidth);$(this).data('thisWidth',thisWidth);var wrapperWidth=$(this).data('wrapperWidth')?$(this).data('wrapperWidth'):0;wrapperWidth=Math.max(wrapper.get(0).scrollWidth,wrapperWidth);wrapper.width(wrapperWidth);$(this).data('wrapperWidth',wrapperWidth);$(this).dialog({'width':wrapper.width()});wrapper.css('left',parseInt(wrapper.css('left'))-(wrapper.width()-oldWidth)/2);} |
508 | | -$(this).css('white-space',oldWS);oldHidden.each(function(){$(this).attr('style',$(this).data('oldstyle'));});}},modules:{},quickDialog:function(body,settings){$('<div />').text(body).appendTo($('body')).dialog($.extend({bgiframe:true,modal:true},settings)).dialog('open');}};})(jQuery);(function($){$.wikiEditor.modules.highlight={cfg:{'styleVersion':3},evt:{delayedChange:function(context,event){if(event.data.scope=='division'){$.wikiEditor.modules.highlight.fn.scan(context,"");$.wikiEditor.modules.highlight.fn.mark(context,"","");}},ready:function(context,event){$.wikiEditor.modules.highlight.fn.scan(context,"");$.wikiEditor.modules.highlight.fn.mark(context,"","");}},fn:{create:function(context,config){},divide:function(context){},isolate:function(context){return[];},strip:function(context,division){return $('<div />').html(division.html().replace(/\<br[^\>]*\>/g,"\n")).text();},scan:function(context,division){function Token(offset,label,tokenStart,match){this.offset=offset;this.label=label;this.tokenStart=tokenStart;this.match=match;} |
| 520 | +$(this).css('white-space',oldWS);oldHidden.each(function(){$(this).attr('style',$(this).data('oldstyle'));});}},modules:{},quickDialog:function(body,settings){$('<div />').text(body).appendTo($('body')).dialog($.extend({bgiframe:true,modal:true},settings)).dialog('open');}};})(jQuery);(function($){$.wikiEditor.modules.highlight={cfg:{'styleVersion':3},evt:{delayedChange:function(context,event){if(event.data.scope=='realchange'){$.wikiEditor.modules.highlight.fn.scan(context,"");$.wikiEditor.modules.highlight.fn.mark(context,"","");}},ready:function(context,event){$.wikiEditor.modules.highlight.fn.scan(context,"");$.wikiEditor.modules.highlight.fn.mark(context,"","");}},fn:{create:function(context,config){context.modules.highlight.markersStr='';},divide:function(context){},isolate:function(context){return[];},strip:function(context,division){return $('<div />').html(division.html().replace(/\<br[^\>]*\>/g,"\n")).text();},scan:function(context,division){function Token(offset,label,tokenStart,match){this.offset=offset;this.label=label;this.tokenStart=tokenStart;this.match=match;} |
509 | 521 | var tokenArray=context.modules.highlight.tokenArray=[];var text=context.fn.getContents();for(module in context.modules){if(module in $.wikiEditor.modules&&'exp'in $.wikiEditor.modules[module]){for(var i=0;i<$.wikiEditor.modules[module].exp.length;i++){var regex=$.wikiEditor.modules[module].exp[i].regex;var label=$.wikiEditor.modules[module].exp[i].label;var markAfter=false;if(typeof $.wikiEditor.modules[module].exp[i].markAfter!='undefined'){markAfter=true;} |
510 | 522 | match=text.match(regex);var oldOffset=0;while(match!=null){var markOffset=0;var tokenStart=match.index+oldOffset+markOffset;if(markAfter){markOffset+=match[0].length;} |
511 | 523 | tokenArray.push(new Token(match.index+oldOffset+markOffset,label,tokenStart,match));oldOffset+=match.index+match[0].length;newSubstring=text.substring(oldOffset);match=newSubstring.match(regex);}}}} |
512 | | -tokenArray.sort(function(a,b){return a.offset-b.offset||a.tokenStart-b.tokenStart;});context.fn.trigger('scan');},mark:function(context,division,tokens){var markers=context.modules.highlight.markers=[];context.fn.trigger('mark');markers.sort(function(a,b){return a.start-b.start||a.end-b.end;});for(var i=0;i<markers.length;i++){var start=markers[i].start;var s=context.fn.getOffset(start);if(!s){continue;} |
513 | | -var startNode=s.node;var startDepth=s.depth;if(s.offset>0){startNode=startNode.splitText(s.offset);} |
514 | | -while(startNode.nodeName=='BR'){start++;s=context.fn.getOffset(start);startNode=s.node;startDepth=s.depth;} |
| 524 | +tokenArray.sort(function(a,b){return a.offset-b.offset||a.tokenStart-b.tokenStart;});context.fn.trigger('scan');},mark:function(context,division,tokens){var markers=context.modules.highlight.markers=[];context.fn.trigger('mark');markers.sort(function(a,b){return a.start-b.start||a.end-b.end;});var markersStr='';for(var i=0;i<markers.length;i++){markersStr+=markers[i].start+','+markers[i].end+','+markers[i].type+',';} |
| 525 | +if(context.modules.highlight.markersStr==markersStr){return;} |
| 526 | +context.modules.highlight.markersStr=markersStr;var visited=[];for(var i=0;i<markers.length;i++){var start=markers[i].start;var s=context.fn.getOffset(start);if(!s){continue;} |
| 527 | +var startNode=s.node;var startDepth=s.depth;while(startNode.nodeName=='BR'||s.offset==startNode.nodeValue.length){start++;s=context.fn.getOffset(start);startNode=s.node;startDepth=s.depth;} |
| 528 | +if(s.offset>0&&s.node.nodeName=='#text'){startNode=startNode.splitText(s.offset);context.fn.purgeOffsets();} |
515 | 529 | var end=markers[i].end;var e=context.fn.getOffset(end);if(!e){continue;} |
516 | | -var endNode=e.node;var endDepth=e.depth;if(e.offset<e.length-1){endNode.splitText(e.offset+1);} |
| 530 | +var endNode=e.node;var endDepth=e.depth;if(e.offset<e.length-1&&e.node.nodeName=='#text'){endNode.splitText(e.offset+1);context.fn.purgeOffsets();} |
517 | 531 | if(endNode.nodeName=='BR'){endNode=e.lastTextNode;endDepth=e.lastTextNodeDepth;} |
518 | 532 | var ca1=startNode,ca2=endNode;if(startDepth>endDepth){for(var j=0;j<startDepth-endDepth&&ca1;j++){ca1=ca1.parentNode.firstChild==ca1?ca1.parentNode:null;}} |
519 | 533 | else if(startDepth<endDepth){for(var j=0;j<endDepth-startDepth&&ca2;j++){ca2=ca2.parentNode.lastChild==ca2?ca2.parentNode:null;}} |
520 | 534 | while(ca1&&ca2&&ca1.parentNode&&ca2.parentNode&&ca1.parentNode!=ca2.parentNode&&ca1.parentNode.firstChild&&ca2.parentNode.lastChild){ca1=ca1.parentNode.firstChild==ca1?ca1.parentNode:null;ca2=ca2.parentNode.lastChild==ca2?ca2.parentNode:null;} |
521 | | -if(ca1&&ca2&&ca1.parentNode&&ca2.nextSibling){var anchor=markers[i].getAnchor(ca1,ca2);if(!anchor){var newNode=ca1.ownerDocument.createElement('div');var commonAncestor=ca1.parentNode;var nextNode=ca2.nextSibling;if(markers[i].anchor=='wrap'){var n=ca1;while(n!=nextNode){var ns=n.nextSibling;newNode.appendChild(n);n=ns;} |
| 535 | +if(ca1&&ca2&&ca1.parentNode){var anchor=markers[i].getAnchor(ca1,ca2);if(!anchor){var newNode=ca1.ownerDocument.createElement('div');var commonAncestor=ca1.parentNode;if(commonAncestor.nodeName=='P'&&commonAncestor.parentNode){commonAncestor=commonAncestor.parentNode;ca1=ca1.parentNode;ca2=ca2.parentNode;} |
| 536 | +var nextNode=ca2.nextSibling;if(markers[i].anchor=='wrap'){var n=ca1;while(n!=nextNode){var ns=n.nextSibling;newNode.appendChild(n);n=ns;} |
522 | 537 | if(nextNode){commonAncestor.insertBefore(newNode,nextNode);}else{commonAncestor.appendChild(newNode);}}else if(markers[i].anchor=='before'){commonAncestor.insertBefore(newNode,ca1);}else if(markers[i].anchor=='after'){if(nextNode){commonAncestor.insertBefore(newNode,nextNode);}else{commonAncestor.appendChild(newNode);}} |
523 | | -$(newNode).data('marker',markers[i]).addClass('wikiEditor-highlight wikiEditor-highlight-tmp');markers[i].afterWrap(newNode,markers[i]);}else{$(anchor).addClass('wikiEditor-highlight-tmp').data('marker',markers[i]);markers[i].onSkip(anchor);}}} |
524 | | -context.$content.find('div.wikiEditor-highlight:not(.wikiEditor-highlight-tmp)').each(function(){if($(this).data('marker')&&typeof $(this).data('marker').unwrap=='function') |
525 | | -$(this).data('marker').unwrap(this);if($(this).children().size()>0){$(this).replaceWith($(this).children());}else{$(this).replaceWith($(this).html());}});context.$content.find('div.wikiEditor-highlight-tmp').removeClass('wikiEditor-highlight-tmp');}}};})(jQuery);(function($){$.wikiEditor.modules.preview={fn:{create:function(context,config){if('initialized'in context.modules.preview){return;} |
| 538 | +$(newNode).data('marker',markers[i]).addClass('wikiEditor-highlight');visited[i]=newNode;markers[i].afterWrap(newNode,markers[i]);}else{visited[i]=anchor;$(anchor).data('marker',markers[i]);markers[i].onSkip(anchor);}}} |
| 539 | +var j=0;context.$content.find('div.wikiEditor-highlight').each(function(){if(visited[j]==this){j++;return true;} |
| 540 | +if($(this).data('marker')&&typeof $(this).data('marker').unwrap=='function') |
| 541 | +$(this).data('marker').unwrap(this);if($(this).children().size()>0){$(this).replaceWith($(this).children());}else{$(this).replaceWith($(this).html());}});}}};})(jQuery);(function($){$.wikiEditor.modules.preview={fn:{create:function(context,config){if('initialized'in context.modules.preview){return;} |
526 | 542 | context.modules.preview={'initialized':true,'previewText':null,'changesText':null};context.modules.preview.$preview=context.fn.addView({'name':'preview','titleMsg':'wikieditor-preview-tab','init':function(context){var wikitext=context.fn.getContents();if(context.modules.preview.previewText==wikitext){return;} |
527 | 543 | context.modules.preview.$preview.find('.wikiEditor-preview-contents').empty();context.modules.preview.$preview.find('.wikiEditor-preview-loading').show();$.post(wgScriptPath+'/api.php',{'action':'parse','title':wgPageName,'text':wikitext,'prop':'text','pst':'','format':'json'},function(data){if(typeof data.parse=='undefined'||typeof data.parse.text=='undefined'||typeof data.parse.text['*']=='undefined'){return;} |
528 | 544 | context.modules.preview.previewText=wikitext;context.modules.preview.$preview.find('.wikiEditor-preview-loading').hide();context.modules.preview.$preview.find('.wikiEditor-preview-contents').html(data.parse.text['*']).find('a:not([href^=#])').click(function(){return false;});},'json');}});context.$changesTab=context.fn.addView({'name':'changes','titleMsg':'wikieditor-preview-changes-tab','init':function(context){var wikitext=context.fn.getContents();if(context.modules.preview.changesText==wikitext){return;} |
— | — | @@ -553,7 +569,7 @@ |
554 | 570 | $('#wikiEditor-'+context.instance+'-dialog-watch').hide();else if($('#wpWatchthis').is(':checked')) |
555 | 571 | $('#wikiEditor-'+context.instance+'-dialog-watch').attr('checked','checked');$(this).find('form').submit(function(e){$(this).closest('.ui-dialog').find('button:first').click();e.preventDefault();});},dialog:{buttons:{'wikieditor-publish-dialog-publish':function(){var minorChecked=$('#wikiEditor-'+context.instance+'-dialog-minor').is(':checked')?'checked':'';var watchChecked=$('#wikiEditor-'+context.instance+'-dialog-watch').is(':checked')?'checked':'';$('#wpMinoredit').attr('checked',minorChecked);$('#wpWatchthis').attr('checked',watchChecked);$('#wpSummary').val($j('#wikiEditor-'+context.instance+'-dialog-summary').val());$('#editform').submit();},'wikieditor-publish-dialog-goback':function(){$(this).dialog('close');}},open:function(){$('#wikiEditor-'+context.instance+'-dialog-summary').focus();},width:500},resizeme:false}});context.fn.addButton({'captionMsg':'wikieditor-publish-button-publish','action':function(){$('#'+dialogID).dialog('open');return false;}});context.fn.addButton({'captionMsg':'wikieditor-publish-button-cancel','action':function(){}});}}};})(jQuery);(function($){$.wikiEditor.modules.templateEditor={evt:{mark:function(context,event){var markers=context.modules.highlight.markers;var tokenArray=context.modules.highlight.tokenArray;var level=0;var tokenIndex=0;while(tokenIndex<tokenArray.length){while(tokenIndex<tokenArray.length&&tokenArray[tokenIndex].label!='TEMPLATE_BEGIN'){tokenIndex++;} |
556 | 572 | if(tokenIndex<tokenArray.length){var beginIndex=tokenIndex;var endIndex=-1;var openTemplates=1;var templatesMatched=false;while(tokenIndex<tokenArray.length-1&&endIndex==-1){tokenIndex++;if(tokenArray[tokenIndex].label=='TEMPLATE_BEGIN'){openTemplates++;}else if(tokenArray[tokenIndex].label=='TEMPLATE_END'){openTemplates--;if(openTemplates==0){endIndex=tokenIndex;}}} |
557 | | -if(endIndex!=-1){markers.push({start:tokenArray[beginIndex].offset,end:tokenArray[endIndex].offset,anchor:'wrap',afterWrap:$.wikiEditor.modules.templateEditor.fn.stylize,beforeUnwrap:function(node){$(node).data('display').remove();},onSkip:function(){},getAnchor:function(ca1,ca2){return $(ca1.parentNode).is('div.wikiEditor-template-text')&&$(ca1.parentNode.previousSibling).is('ul.wikiEditor-template-modes')&&ca1.parentNode.nextSibling==null?ca1.parentNode:null;}});}else{tokenArray[beginIndex].label='TEMPLATE_FALSE_BEGIN';tokenIndex=beginIndex;}}}}},exp:[{'regex':/{{/,'label':"TEMPLATE_BEGIN"},{'regex':/}}/,'label':"TEMPLATE_END",'markAfter':true}],cfg:{},fn:{create:function(context,config){context.modules.templateEditor={};},stylize:function(wrappedTemplate){$(wrappedTemplate).each(function(){if(typeof $(this).data('model')!='undefined'){return;} |
| 573 | +if(endIndex!=-1){markers.push({start:tokenArray[beginIndex].offset,end:tokenArray[endIndex].offset,type:'template',anchor:'wrap',afterWrap:$.wikiEditor.modules.templateEditor.fn.stylize,beforeUnwrap:function(node){$(node).data('display').remove();},onSkip:function(){},getAnchor:function(ca1,ca2){return $(ca1.parentNode).is('div.wikiEditor-template-text')&&$(ca1.parentNode.previousSibling).is('ul.wikiEditor-template-modes')&&ca1.parentNode.nextSibling==null?ca1.parentNode:null;}});}else{tokenArray[beginIndex].label='TEMPLATE_FALSE_BEGIN';tokenIndex=beginIndex;}}}}},exp:[{'regex':/{{/,'label':"TEMPLATE_BEGIN"},{'regex':/}}/,'label':"TEMPLATE_END",'markAfter':true}],cfg:{},fn:{create:function(context,config){context.modules.templateEditor={};},stylize:function(wrappedTemplate){$(wrappedTemplate).each(function(){if(typeof $(this).data('model')!='undefined'){return;} |
558 | 574 | var model=new $.wikiEditor.modules.templateEditor.fn.model($(this).text());if(!model.isCollapsible()){return;} |
559 | 575 | var $template=$(this).wrap('<div class="wikiEditor-template"></div>').addClass('wikiEditor-template-text wikiEditor-nodisplay').html($(this).html().replace(/\{\{/,'<span class="wikiEditor-template-start">{{</span><span class="wikiEditor-template-inner-text">').replace(/\}\}$/,'</span><span class="wikiEditor-template-end">}}</span>')).css('visibility','hidden').parent().addClass('wikiEditor-template-collapsed').data('model',model);$('<span />').addClass('wikiEditor-template-name wikiEditor-noinclude').text(model.getName()).mousedown(noEdit).prependTo($template);$template.find('.wikiEditor-template-end, .wikiEditor-template-start').mousedown(toggleWikiText);var $options=$('<ul />').addClass('wikiEditor-template-modes wikiEditor-noinclude').append($('<li />').addClass('wikiEditor-template-action-wikiText').append($('<img />').attr('src',$.wikiEditor.imgPath+'templateEditor/'+'wiki-text.png')).mousedown(toggleWikiText)).insertAfter($template.find('.wikiEditor-template-name'));$options.append($('<li />').addClass('wikiEditor-template-action-form').append($('<span>F</span>')).mousedown(function(){createDialog($template);return false;}));function expandTemplate($displayDiv){$displayDiv.removeClass('wikiEditor-template-collapsed');$displayDiv.addClass('wikiEditor-template-expanded');$displayDiv.unbind('mousedown');$keyValueTable=$('<table />').appendTo($displayDiv);$header_row=$('<tr />').appendTo($keyValueTable);$('<th />').attr('colspan','2').text(model.getName()).appendTo($header_row);for(param in model.getAllParamNames()){$keyVal_row=$('<tr />').appendTo($keyValueTable);$('<td />').text(param).appendTo($keyVal_row);$('<td />').text(model.getValue(param)).appendTo($keyVal_row);}};function collapseTemplate($displayDiv){$displayDiv.addClass('wikiEditor-template-collapsed');$displayDiv.removeClass('wikiEditor-template-expanded');$displayDiv.text(model.getName());};function createDialog($templateDiv){var templateModel=$templateDiv.data('model');var $dialog=$("<div></div>");var $title=$("<div>"+templateModel.getName()+"</div>").addClass('wikiEditor-template-dialog-title');var $table=$("<table></table>").addClass('wikiEditor-template-dialog-table').appendTo($dialog);var allInitialParams=templateModel.getAllInitialParams();for(var paramIndex in allInitialParams){var param=allInitialParams[paramIndex];if(typeof param.name=='undefined'){continue;} |
560 | 576 | var $paramRow=$("<tr></tr>").addClass('wikiEditor-template-dialog-row');var $paramName=$("<td></td>").addClass('wikiEditor-template-dialog-name').text(param.name);var $paramVal=$("<td></td>").addClass('wikiEditor-template-dialog-value');var $paramInput=$("<input></input>").data('name',param.name).val(templateModel.getValue(param.name));$paramVal.append($paramInput);$paramRow.append($paramName).append($paramVal);$table.append($paramRow);} |
— | — | @@ -594,21 +610,21 @@ |
595 | 611 | if(context.modules.toc.$toc.data('positionMode')=='goofy'){context.modules.toc.$toc.find('div').autoEllipsis({'position':'right','tooltip':true,'restoreText':true});} |
596 | 612 | if(!context.modules.toc.$toc.data('collapsed')){context.modules.toc.$toc.height(context.$ui.find('.wikiEditor-ui-left').height()- |
597 | 613 | context.$ui.find('.tab-toc').outerHeight());} |
598 | | -context.modules.toc.$toc.data('previousWidth',context.$wikitext.width());},mark:function(context,event){var markers=context.modules.highlight.markers;var tokenArray=context.modules.highlight.tokenArray;var outline=context.data.outline=[];var h=0;for(var i=0;i<tokenArray.length;i++){if(tokenArray[i].label!='TOC_HEADER'){continue;} |
599 | | -h++;markers.push({index:h,start:tokenArray[i].tokenStart,end:tokenArray[i].offset,anchor:'before',afterWrap:function(node){var marker=$(node).data('marker');$(node).addClass('wikiEditor-toc-header').addClass('wikiEditor-toc-section-'+marker.index).data('section',marker.index);},onSkip:function(node){var marker=$(node).data('marker');$(node).removeClass('wikiEditor-toc-section-'+$(node).data('section')).addClass('wikiEditor-toc-section-'+marker.index).data('section',marker.index);},getAnchor:function(ca1,ca2){return $(ca1.previousSibling).is('div.wikiEditor-toc-header')?ca1.previousSibling:null;}});outline.push({'text':tokenArray[i].match[2],'level':tokenArray[i].match[1].length,'index':h});} |
600 | | -$.wikiEditor.modules.toc.fn.build(context);$.wikiEditor.modules.toc.fn.update(context);}},exp:[{'regex':/^(={1,6})([^\r\n]+?)\1\s*$/m,'label':'TOC_HEADER','markAfter':true}],fn:{create:function(context,config){if('$toc'in context.modules.toc){return;} |
| 614 | +context.modules.toc.$toc.data('previousWidth',context.$wikitext.width());},mark:function(context,event){var hash='';var markers=context.modules.highlight.markers;var tokenArray=context.modules.highlight.tokenArray;var outline=context.data.outline=[];var h=0;for(var i=0;i<tokenArray.length;i++){if(tokenArray[i].label!='TOC_HEADER'){continue;} |
| 615 | +h++;markers.push({index:h,start:tokenArray[i].tokenStart,end:tokenArray[i].offset,type:'toc',anchor:'before',afterWrap:function(node){var marker=$(node).data('marker');$(node).addClass('wikiEditor-toc-header').addClass('wikiEditor-toc-section-'+marker.index).data('section',marker.index);},onSkip:function(node){var marker=$(node).data('marker');if($(node).data('section')!=marker.index){$(node).removeClass('wikiEditor-toc-section-'+$(node).data('section')).addClass('wikiEditor-toc-section-'+marker.index).data('section',marker.index);}},getAnchor:function(ca1,ca2){return $(ca1.parentNode.previousSibling).is('div.wikiEditor-toc-header')?ca1.parentNode.previousSibling:null;}});hash+=tokenArray[i].match[2]+'\n';outline.push({'text':tokenArray[i].match[2],'level':tokenArray[i].match[1].length,'index':h});} |
| 616 | +if(typeof context.modules.toc.lastHash=='undefined'||context.modules.toc.lastHash!==hash){$.wikiEditor.modules.toc.fn.build(context);$.wikiEditor.modules.toc.fn.update(context);context.modules.toc.lastHash=hash;}}},exp:[{'regex':/^(={1,6})([^\r\n]+?)\1\s*$/m,'label':'TOC_HEADER','markAfter':true}],fn:{create:function(context,config){if('$toc'in context.modules.toc){return;} |
601 | 617 | $.wikiEditor.modules.toc.cfg.rtl=config.rtl;var height=context.$ui.find('.wikiEditor-ui-left').height();context.modules.toc.$toc=$('<div />').addClass('wikiEditor-ui-toc').data('context',context).data('positionMode','regular').data('collapsed',false);context.$ui.find('.wikiEditor-ui-right').append(context.modules.toc.$toc);context.modules.toc.$toc.height(context.$ui.find('.wikiEditor-ui-left').height());$.wikiEditor.modules.toc.fn.redraw(context,$.wikiEditor.modules.toc.cfg.defaultWidth);},redraw:function(context,fixedWidth){var fixedWidth=parseFloat(fixedWidth);if(context.modules.toc.$toc.data('positionMode')=='regular'){context.$ui.find('.wikiEditor-ui-right').css('width',fixedWidth+'px');context.$ui.find('.wikiEditor-ui-left').css('marginRight',(-1*fixedWidth)+'px').children().css('marginRight',fixedWidth+'px');}else if(context.modules.toc.$toc.data('positionMode')=='goofy'){context.$ui.find('.wikiEditor-ui-left').css('width',fixedWidth);context.$ui.find('.wikiEditor-ui-right').css($.wikiEditor.modules.toc.cfg.rtl?'right':'left',fixedWidth);context.$wikitext.css('height',context.$ui.find('.wikiEditor-ui-right').height());}},switchLayout:function(context){var width,height=context.$ui.find('.wikiEditor-ui-right').height();if(context.modules.toc.$toc.data('positionMode')=='regular'&&!context.modules.toc.$toc.data('collapsed')){context.modules.toc.$toc.data('positionMode','goofy');context.modules.toc.$toc.data('positionModeChangeAt',context.$ui.find('.wikiEditor-ui-right').width());width=$.wikiEditor.modules.toc.cfg.textMinimumWidth;context.$ui.find('.wikiEditor-ui-left').css({'marginRight':'','position':'absolute','float':'none','left':$.wikiEditor.modules.toc.cfg.rtl?'auto':0,'right':$.wikiEditor.modules.toc.cfg.rtl?0:'auto'}).children().css('marginRight','');context.$ui.find('.wikiEditor-ui-right').css({'width':'auto','position':'absolute','float':'none','right':$.wikiEditor.modules.toc.cfg.rtl?'auto':0,'left':$.wikiEditor.modules.toc.cfg.rtl?0:'auto'});context.$wikitext.css('position','relative');}else if(context.modules.toc.$toc.data('positionMode')=='goofy'){context.modules.toc.$toc.data('positionMode','regular');width=context.$wikitext.width()-context.$ui.find('.wikiEditor-ui-left').width();if(width>context.modules.toc.$toc.data('positionModeChangeAt')){width=context.modules.toc.$toc.data('positionModeChangeAt');} |
602 | 618 | context.$wikitext.css({'position':'','height':''});context.$ui.find('.wikiEditor-ui-right').css({'marginRight':'','position':'','left':'','right':'','float':'','top':'','height':''});context.$ui.find('.wikiEditor-ui-left').css({'width':'','position':'','left':'','float':'','right':''});} |
603 | 619 | $.wikiEditor.modules.toc.fn.redraw(context,width);},disable:function(context){if(context.modules.toc.$toc.data('collapsed')){context.$ui.find('.wikiEditor-ui-toc-expandControl').hide();}else{if(context.modules.toc.$toc.data('positionMode')=='goofy'){$.wikiEditor.modules.toc.fn.switchLayout(context);} |
604 | 620 | context.$ui.find('.wikiEditor-ui-right').hide();context.$ui.find('.wikiEditor-ui-left').css('marginRight','').children().css('marginRight','');} |
605 | | -context.modules.toc.$toc.data('positionMode','disabled');},enable:function(context){context.modules.toc.$toc.data('positionMode','regular');if(context.modules.toc.$toc.data('collapsed')){context.$ui.find('.wikiEditor-ui-toc-expandControl').show();}else{context.$ui.find('.wikiEditor-ui-right').show();$.wikiEditor.modules.toc.fn.redraw(context,$.wikiEditor.modules.toc.cfg.minimumWidth);context.modules.toc.$toc.find('div').autoEllipsis({'position':'right','tooltip':true,'restoreText':true});}},unhighlight:function(context){if(context){context.modules.toc.$toc.find('div').removeClass('current');}},update:function(context){$.wikiEditor.modules.toc.fn.unhighlight(context);var div=context.fn.beforeSelection('div.wikiEditor-toc-header');var section=div.data('section')||0;if(context.data.outline.length>0){var sectionLink=context.modules.toc.$toc.find('div.section-'+section);sectionLink.addClass('current');var relTop=sectionLink.offset().top-context.modules.toc.$toc.offset().top;var scrollTop=context.modules.toc.$toc.scrollTop();var divHeight=context.modules.toc.$toc.height();var sectionHeight=sectionLink.height();if(relTop<0) |
| 621 | +context.modules.toc.$toc.data('positionMode','disabled');},enable:function(context){context.modules.toc.$toc.data('positionMode','regular');if(context.modules.toc.$toc.data('collapsed')){context.$ui.find('.wikiEditor-ui-toc-expandControl').show();}else{context.$ui.find('.wikiEditor-ui-right').show();$.wikiEditor.modules.toc.fn.redraw(context,$.wikiEditor.modules.toc.cfg.minimumWidth);context.modules.toc.$toc.find('div').autoEllipsis({'position':'right','tooltip':true,'restoreText':true});}},unhighlight:function(context){if(context){context.modules.toc.$toc.find('div').removeClass('current');}},update:function(context){$.wikiEditor.modules.toc.fn.unhighlight(context);var div=context.fn.beforeSelection('wikiEditor-toc-header');var section=div.data('section')||0;if(context.data.outline.length>0){var sectionLink=context.modules.toc.$toc.find('div.section-'+section);sectionLink.addClass('current');var relTop=sectionLink.offset().top-context.modules.toc.$toc.offset().top;var scrollTop=context.modules.toc.$toc.scrollTop();var divHeight=context.modules.toc.$toc.height();var sectionHeight=sectionLink.height();if(relTop<0) |
606 | 622 | context.modules.toc.$toc.scrollTop(scrollTop+relTop);else if(relTop+sectionHeight>divHeight) |
607 | 623 | context.modules.toc.$toc.scrollTop(scrollTop+relTop+sectionHeight-divHeight);}},collapse:function(event){var $this=$(this),context=$this.data('context');if(context.modules.toc.$toc.data('positionMode')=='goofy'){$.wikiEditor.modules.toc.fn.switchLayout(context);} |
608 | 624 | var pT=$this.parent().position().top-1;context.modules.toc.$toc.data('collapsed',true);context.$ui.find('.wikiEditor-ui-left').animate({'marginRight':'-1px'},'fast',function(){$(this).css('marginRight',0);}).children().animate({'marginRight':'1px'},'fast',function(){$(this).css('marginRight',0);});context.$ui.find('.wikiEditor-ui-right').css({'marginTop':'1px','position':'absolute','left':$.wikiEditor.modules.toc.cfg.rtl?0:'auto','right':$.wikiEditor.modules.toc.cfg.rtl?'auto':0,'top':pT}).fadeOut('fast',function(){$(this).hide().css({'marginTop':'0','width':'1px'});context.$ui.find('.wikiEditor-ui-toc-expandControl').fadeIn('fast');context.fn.trigger('tocCollapse');context.fn.trigger('resize');});$.cookie('wikiEditor-'+context.instance+'-toc-width',0);return false;},expand:function(event){var $this=$(this),context=$this.data('context'),openWidth=parseFloat(context.modules.toc.$toc.data('openWidth')),availableSpace=context.$wikitext.width()-parseFloat($.wikiEditor.modules.toc.cfg.textMinimumWidth);if(availableSpace<$.wikiEditor.modules.toc.cfg.textMinmumWidth)return false;context.modules.toc.$toc.data('collapsed',false);if(availableSpace<openWidth)openWidth=availableSpace;context.$ui.find('.wikiEditor-ui-toc-expandControl').hide();context.$ui.find('.wikiEditor-ui-left').animate({'marginRight':(parseFloat(openWidth)*-1)},'fast').children().animate({'marginRight':openWidth},'fast');context.$ui.find('.wikiEditor-ui-right').show().css('marginTop','1px').animate({'width':openWidth},'fast',function(){context.$content.trigger('mouseup');$(this).css({'marginTop':'0','position':'relative','right':'auto','left':'auto','top':'auto'});context.fn.trigger('tocExpand');context.fn.trigger('resize');});$.cookie('wikiEditor-'+context.instance+'-toc-width',context.modules.toc.$toc.data('openWidth'));return false;},build:function(context){function buildStructure(outline,offset,level){if(offset==undefined)offset=0;if(level==undefined)level=1;var sections=[];for(var i=offset;i<outline.length;i++){if(outline[i].nLevel==level){var sub=buildStructure(outline,i+1,level+1);if(sub.length){outline[i].sections=sub;} |
609 | 625 | sections[sections.length]=outline[i];}else if(outline[i].nLevel<level){break;}} |
610 | 626 | return sections;} |
611 | | -function buildList(structure){var list=$('<ul />');for(i in structure){var wrapper=context.$content.find('.wikiEditor-toc-section-'+structure[i].index);if(wrapper.size()==0) |
612 | | -wrapper=context.$content;var div=$('<div />').addClass('section-'+structure[i].index).data('wrapper',wrapper).click(function(event){context.fn.scrollToTop($(this).data('wrapper'),true);context.$textarea.textSelection('setSelection',{'start':0,'startContainer':$(this).data('wrapper')});$.wikiEditor.modules.toc.fn.unhighlight(context);$(this).addClass('current');if(typeof $.trackAction!='undefined') |
| 627 | +function buildList(structure){var list=$('<ul />');for(i in structure){var div=$('<div />').addClass('section-'+structure[i].index).data('index',structure[i].index).click(function(event){var wrapper=context.$content.find('.wikiEditor-toc-section-'+$(this).data('index'));if(wrapper.size()==0) |
| 628 | +wrapper=context.$content;context.fn.scrollToTop(wrapper,true);context.$textarea.textSelection('setSelection',{'start':0,'startContainer':wrapper});$.wikiEditor.modules.toc.fn.unhighlight(context);$(this).addClass('current');if(typeof $.trackAction!='undefined') |
613 | 629 | $.trackAction('ntoc.heading');event.preventDefault();}).text(structure[i].text);if(structure[i].text=='') |
614 | 630 | div.html(' ');var item=$('<li />').append(div);if(structure[i].sections!==undefined){item.append(buildList(structure[i].sections));} |
615 | 631 | list.append(item);} |
— | — | @@ -644,7 +660,7 @@ |
645 | 661 | rels.reverse();var id=rels.join('.');$.trackAction(id);} |
646 | 662 | switch(action.type){case'replace':case'encapsulate':var parts={'pre':'','peri':'','post':''};for(part in parts){if(part+'Msg'in action.options){parts[part]=mw.usability.getMsg(action.options[part+'Msg'],(action.options[part]||null));}else{parts[part]=(action.options[part]||'')}} |
647 | 663 | if('regex'in action.options&&'regexReplace'in action.options){var selection=context.$textarea.textSelection('getSelection');if(selection!=''&&selection.match(action.options.regex)){parts.peri=selection.replace(action.options.regex,action.options.regexReplace);parts.pre=parts.post='';}} |
648 | | -context.$textarea.textSelection('encapsulateSelection',$.extend({},action.options,parts,{'replace':action.type=='replace'}));break;case'callback':if(typeof action.execute=='function'){action.execute(context);} |
| 664 | +context.$textarea.textSelection('encapsulateSelection',$.extend({},action.options,parts,{'replace':action.type=='replace'}));context.$iframe[0].contentWindow.focus();break;case'callback':if(typeof action.execute=='function'){action.execute(context);} |
649 | 665 | break;case'dialog':context.$textarea.wikiEditor('openDialog',action.module);break;default:break;}},buildGroup:function(context,id,group){var $group=$('<div />').attr({'class':'group group-'+id,'rel':id});var label=$.wikiEditor.autoMsg(group,'label');if(label){$group.append('<div class="label">'+label+'</div>')} |
650 | 666 | var empty=true;if('tools'in group){for(tool in group.tools){var tool=$.wikiEditor.modules.toolbar.fn.buildTool(context,tool,group.tools[tool]);if(tool){empty=false;$group.append(tool);}}} |
651 | 667 | return empty?null:$group;},buildTool:function(context,id,tool){if('filters'in tool){for(filter in tool.filters){if($(tool.filters[filter]).size()==0){return null;}}} |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/js/plugins/jquery.wikiEditor.templateEditor.js |
— | — | @@ -38,6 +38,7 @@ |
39 | 39 | markers.push( { |
40 | 40 | start: tokenArray[beginIndex].offset, |
41 | 41 | end: tokenArray[endIndex].offset, |
| 42 | + type: 'template', |
42 | 43 | anchor: 'wrap', |
43 | 44 | afterWrap: $.wikiEditor.modules.templateEditor.fn.stylize, |
44 | 45 | beforeUnwrap: function( node ) { |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/js/plugins/jquery.wikiEditor.toc.js |
— | — | @@ -73,6 +73,7 @@ |
74 | 74 | context.modules.toc.$toc.data( 'previousWidth', context.$wikitext.width() ); |
75 | 75 | }, |
76 | 76 | mark: function( context, event ) { |
| 77 | + var hash = ''; |
77 | 78 | var markers = context.modules.highlight.markers; |
78 | 79 | var tokenArray = context.modules.highlight.tokenArray; |
79 | 80 | var outline = context.data.outline = []; |
— | — | @@ -86,6 +87,7 @@ |
87 | 88 | index: h, |
88 | 89 | start: tokenArray[i].tokenStart, |
89 | 90 | end: tokenArray[i].offset, |
| 91 | + type: 'toc', |
90 | 92 | anchor: 'before', |
91 | 93 | afterWrap: function( node ) { |
92 | 94 | var marker = $( node ).data( 'marker' ); |
— | — | @@ -95,24 +97,32 @@ |
96 | 98 | }, |
97 | 99 | onSkip: function( node ) { |
98 | 100 | var marker = $( node ).data( 'marker' ); |
99 | | - $( node ) |
100 | | - .removeClass( 'wikiEditor-toc-section-' + $( node ).data( 'section' ) ) |
101 | | - .addClass( 'wikiEditor-toc-section-' + marker.index ) |
102 | | - .data( 'section', marker.index ); |
| 101 | + if ( $( node ).data( 'section' ) != marker.index ) { |
| 102 | + $( node ) |
| 103 | + .removeClass( 'wikiEditor-toc-section-' + $( node ).data( 'section' ) ) |
| 104 | + .addClass( 'wikiEditor-toc-section-' + marker.index ) |
| 105 | + .data( 'section', marker.index ); |
| 106 | + } |
103 | 107 | }, |
104 | 108 | getAnchor: function( ca1, ca2 ) { |
105 | | - return $( ca1.previousSibling ).is( 'div.wikiEditor-toc-header' ) ? |
106 | | - ca1.previousSibling : null; |
| 109 | + return $( ca1.parentNode.previousSibling ).is( 'div.wikiEditor-toc-header' ) ? |
| 110 | + ca1.parentNode.previousSibling : null; |
107 | 111 | } |
108 | 112 | } ); |
| 113 | + hash += tokenArray[i].match[2] + '\n'; |
109 | 114 | outline.push ( { |
110 | 115 | 'text': tokenArray[i].match[2], |
111 | 116 | 'level': tokenArray[i].match[1].length, |
112 | 117 | 'index': h |
113 | 118 | } ); |
114 | 119 | } |
115 | | - $.wikiEditor.modules.toc.fn.build( context ); |
116 | | - $.wikiEditor.modules.toc.fn.update( context ); |
| 120 | + // Only update the TOC if it's been changed - we do this by comparing a hash of the headings this time to last |
| 121 | + if ( typeof context.modules.toc.lastHash == 'undefined' || context.modules.toc.lastHash !== hash ) { |
| 122 | + $.wikiEditor.modules.toc.fn.build( context ); |
| 123 | + $.wikiEditor.modules.toc.fn.update( context ); |
| 124 | + // Remember the changed version |
| 125 | + context.modules.toc.lastHash = hash; |
| 126 | + } |
117 | 127 | } |
118 | 128 | }, |
119 | 129 | exp: [ |
— | — | @@ -249,7 +259,7 @@ |
250 | 260 | update: function( context ) { |
251 | 261 | $.wikiEditor.modules.toc.fn.unhighlight( context ); |
252 | 262 | |
253 | | - var div = context.fn.beforeSelection( 'div.wikiEditor-toc-header' ); |
| 263 | + var div = context.fn.beforeSelection( 'wikiEditor-toc-header' ); |
254 | 264 | var section = div.data( 'section' ) || 0; |
255 | 265 | if ( context.data.outline.length > 0 ) { |
256 | 266 | var sectionLink = context.modules.toc.$toc.find( 'div.section-' + section ); |
— | — | @@ -383,17 +393,18 @@ |
384 | 394 | function buildList( structure ) { |
385 | 395 | var list = $( '<ul />' ); |
386 | 396 | for ( i in structure ) { |
387 | | - var wrapper = context.$content.find( '.wikiEditor-toc-section-' + structure[i].index ); |
388 | | - if ( wrapper.size() == 0 ) |
389 | | - wrapper = context.$content; |
390 | 397 | var div = $( '<div />' ) |
391 | 398 | .addClass( 'section-' + structure[i].index ) |
392 | | - .data( 'wrapper', wrapper ) |
| 399 | + .data( 'index', structure[i].index ) |
393 | 400 | .click( function( event ) { |
394 | | - context.fn.scrollToTop( $( this ).data( 'wrapper' ), true ); |
| 401 | + var wrapper = context.$content.find( |
| 402 | + '.wikiEditor-toc-section-' + $( this ).data( 'index' ) ); |
| 403 | + if ( wrapper.size() == 0 ) |
| 404 | + wrapper = context.$content; |
| 405 | + context.fn.scrollToTop( wrapper, true ); |
395 | 406 | context.$textarea.textSelection( 'setSelection', { |
396 | 407 | 'start': 0, |
397 | | - 'startContainer': $(this).data( 'wrapper' ) |
| 408 | + 'startContainer': wrapper |
398 | 409 | } ); |
399 | 410 | // Highlight the clicked link |
400 | 411 | $.wikiEditor.modules.toc.fn.unhighlight( context ); |
— | — | @@ -488,7 +499,9 @@ |
489 | 500 | if( ui.size.width <= parseFloat( $.wikiEditor.modules.toc.cfg.minimumWidth ) ) { |
490 | 501 | context.modules.toc.$toc.trigger( 'collapse.wikiEditor-toc' ); |
491 | 502 | } else { |
492 | | - context.modules.toc.$toc.find( 'div' ).autoEllipsis( { 'position': 'right', 'tooltip': true, 'restoreText': true } ); |
| 503 | + context.modules.toc.$toc.find( 'div' ).autoEllipsis( |
| 504 | + { 'position': 'right', 'tooltip': true, 'restoreText': true } |
| 505 | + ); |
493 | 506 | context.modules.toc.$toc.data( 'openWidth', ui.size.width ); |
494 | 507 | $.cookie( 'wikiEditor-' + context.instance + '-toc-width', ui.size.width ); |
495 | 508 | } |
— | — | @@ -552,7 +565,9 @@ |
553 | 566 | buildResizeControls(); |
554 | 567 | buildCollapseControls(); |
555 | 568 | } |
556 | | - context.modules.toc.$toc.find( 'div' ).autoEllipsis( { 'position': 'right', 'tooltip': true, 'restoreText': true } ); |
| 569 | + context.modules.toc.$toc.find( 'div' ).autoEllipsis( |
| 570 | + { 'position': 'right', 'tooltip': true, 'restoreText': true } |
| 571 | + ); |
557 | 572 | } |
558 | 573 | } |
559 | 574 | } |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/js/plugins/jquery.wikiEditor.js |
— | — | @@ -89,7 +89,7 @@ |
90 | 90 | } |
91 | 91 | // Check over each browser condition to determine if we are running in a compatible client |
92 | 92 | var browser = $.wikiEditor.browsers[$( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'][$.browser.name]; |
93 | | - for ( condition in browser ) { |
| 93 | + for ( var condition in browser ) { |
94 | 94 | var op = browser[condition][0]; |
95 | 95 | var val = browser[condition][1]; |
96 | 96 | if ( typeof val == 'string' ) { |
— | — | @@ -118,7 +118,7 @@ |
119 | 119 | 'autoMsg': function( object, property ) { |
120 | 120 | // Accept array of possible properties, of which the first one found will be used |
121 | 121 | if ( typeof property == 'object' ) { |
122 | | - for ( i in property ) { |
| 122 | + for ( var i in property ) { |
123 | 123 | if ( property[i] in object || property[i] + 'Msg' in object ) { |
124 | 124 | property = property[i]; |
125 | 125 | break; |
— | — | @@ -199,7 +199,13 @@ |
200 | 200 | // Unique numeric ID of this instance used both for looking up and differentiating instances of wikiEditor |
201 | 201 | 'instance': $.wikiEditor.instances.push( $(this) ) - 1, |
202 | 202 | // Array mapping elements in the textarea to character offsets |
203 | | - 'offsets': null |
| 203 | + 'offsets': null, |
| 204 | + // Cache for context.fn.htmlToText() |
| 205 | + 'htmlToTextMap': {}, |
| 206 | + // The previous HTML of the iframe, stored to detect whether something really changed. |
| 207 | + 'oldHTML': null, |
| 208 | + // Same for delayedChange() |
| 209 | + 'oldDelayedHTML': null |
204 | 210 | }; |
205 | 211 | |
206 | 212 | /* |
— | — | @@ -223,12 +229,12 @@ |
224 | 230 | } else if ( typeof data == 'object' ) { |
225 | 231 | modules = data; |
226 | 232 | } |
227 | | - for ( module in modules ) { |
| 233 | + for ( var module in modules ) { |
228 | 234 | // Check for the existance of an available module with a matching name and a create function |
229 | 235 | if ( typeof module == 'string' && module in $.wikiEditor.modules ) { |
230 | 236 | // Extend the context's core API with this module's own API calls |
231 | 237 | if ( 'api' in $.wikiEditor.modules[module] ) { |
232 | | - for ( call in $.wikiEditor.modules[module].api ) { |
| 238 | + for ( var call in $.wikiEditor.modules[module].api ) { |
233 | 239 | // Modules may not overwrite existing API functions - first come, first serve |
234 | 240 | if ( !( call in context.api ) ) { |
235 | 241 | context.api[call] = $.wikiEditor.modules[module].api[call]; |
— | — | @@ -262,12 +268,23 @@ |
263 | 269 | */ |
264 | 270 | 'change': function( event ) { |
265 | 271 | event.data.scope = 'division'; |
266 | | - context.fn.purgeOffsets(); |
| 272 | + var newHTML = context.$content.html(); |
| 273 | + if ( context.oldHTML != newHTML ) { |
| 274 | + context.fn.purgeOffsets(); |
| 275 | + context.oldHTML = newHTML; |
| 276 | + event.data.scope = 'realchange'; |
| 277 | + } |
267 | 278 | return true; |
268 | 279 | }, |
269 | 280 | 'delayedChange': function( event ) { |
270 | | - // Redirect - since we want the same functionality |
271 | | - return context.evt.change( event ); |
| 281 | + event.data.scope = 'division'; |
| 282 | + var newHTML = context.$content.html(); |
| 283 | + if ( context.oldDelayedHTML != newHTML ) { |
| 284 | + context.fn.purgeOffsets(); |
| 285 | + context.oldDelayedHTML = newHTML; |
| 286 | + event.data.scope = 'realchange'; |
| 287 | + } |
| 288 | + return true; |
272 | 289 | } |
273 | 290 | }; |
274 | 291 | |
— | — | @@ -293,7 +310,7 @@ |
294 | 311 | } |
295 | 312 | } |
296 | 313 | // Pass the event around to all modules activated on this context |
297 | | - for ( module in context.modules ) { |
| 314 | + for ( var module in context.modules ) { |
298 | 315 | if ( |
299 | 316 | module in $.wikiEditor.modules && |
300 | 317 | 'evt' in $.wikiEditor.modules[module] && |
— | — | @@ -360,22 +377,71 @@ |
361 | 378 | .appendTo( context.$ui ); |
362 | 379 | }, |
363 | 380 | 'htmlToText': function( html ) { |
| 381 | + // This function is slow for large inputs, so aggressively cache input/output pairs |
| 382 | + if ( html in context.htmlToTextMap ) { |
| 383 | + return context.htmlToTextMap[html]; |
| 384 | + } |
| 385 | + var origHTML = html; |
| 386 | + |
364 | 387 | // We use this elaborate trickery for cross-browser compatibility |
365 | 388 | // IE does overzealous whitespace collapsing for $( '<pre />' ).html( html ); |
366 | | - var $pre = $( '<pre>' + |
367 | | - html |
| 389 | + // We also do <br> and easy cases for <p> conversion here, complicated cases are handled later |
| 390 | + html = html |
368 | 391 | .replace( /\r?\n/g, "" ) // IE7 inserts newlines before block elements |
369 | | - .replace( /\<br[^\>]*\>/gi, "\n" ) |
370 | 392 | .replace( / /g, " " ) // We inserted these to prevent IE from collapsing spaces |
371 | | - .replace( /\<p[^\>]*\>/gi, "\n" ) // IE uses </p><p> for user-inserted line breaks |
372 | | - .replace( /\<\/p[^\>]*\>/gi, "" ) |
373 | | - .replace( /\<div[^\>]*\>/gi, "\n" ) // Webkit uses </div><div> for user-inserted line breaks |
374 | | - .replace( /\<\/div[^\>]*\>/gi, "" ) |
375 | | - + '</pre>' ); |
376 | | - // Get rid of the noincludes when getting text |
| 393 | + .replace( /\<br[^\>]*\>/gi, "\n" ) // <br> conversion |
| 394 | + .replace( /\<\/p\>\<p\>/gi, "\n" ) // Easy case for <p> conversion |
| 395 | + .replace( /\<\/p\>(\n*)\<p\>/gi, "$1\n" ); |
| 396 | + // Save leading and trailing whitespace now and restore it later. IE eats it all, and even Firefox |
| 397 | + // won't leave everything alone |
| 398 | + var leading = html.match( /^\s*/ )[0]; |
| 399 | + var trailing = html.match( /\s*$/ )[0]; |
| 400 | + html = html.substr( leading.length, html.length - leading.length - trailing.length ); |
| 401 | + var $pre = $( '<pre>' + html + '</pre>' ); |
377 | 402 | $pre.find( '.wikiEditor-noinclude' ).each( function() { $( this ).remove(); } ); |
378 | | - $pre.find( '.wikiEditor-tab' ).each( function() { $( this ).text( "\t" ) } ); |
379 | | - return $pre.text(); |
| 403 | + // Convert tabs, <p>s and <br>s back |
| 404 | + $pre.find( '.wikiEditor-tab' ).each( function() { $( this ).text( "\t" ); } ); |
| 405 | + $pre.find( 'br' ).each( function() { $( this ).replaceWith( "\n" ); } ); |
| 406 | + // Converting <p>s is wrong if there's nothing before them, so check that. |
| 407 | + // .find( '* + p' ) isn't good enough because textnodes aren't considered |
| 408 | + $pre.find( 'p' ).each( function() { |
| 409 | + if ( this.previousSibling || this.parentNode != $pre.get( 0 ) ) { |
| 410 | + var text = $( this ).text(); |
| 411 | + // If this <p> is preceded by some text, add a \n at the beginning, and if |
| 412 | + // it's followed by a textnode, add a \n at the end |
| 413 | + // We need the traverser because there can be other weird stuff in between |
| 414 | + |
| 415 | + // Check for preceding text |
| 416 | + // FIXME: Add an option to disable depth checking, -10 is a hack |
| 417 | + var t = new context.fn.rawTraverser( this.firstChild, -10, this ).prev(); |
| 418 | + while ( t && t.node.nodeName != '#text' && t.node.nodeName != 'BR' && t.node.nodeName != 'P' ) { |
| 419 | + t = t.prev(); |
| 420 | + } |
| 421 | + if ( t ) { |
| 422 | + text = "\n" + text; |
| 423 | + } |
| 424 | + |
| 425 | + // Check for following text |
| 426 | + t = new context.fn.rawTraverser( this.lastChild, -10, this ).next(); |
| 427 | + while ( t && t.node.nodeName != '#text' && t.node.nodeName != 'BR' && t.node.nodeName != 'P' ) { |
| 428 | + t = t.next(); |
| 429 | + } |
| 430 | + if ( t && !t.inP && t.node.nodeName == '#text' && t.node.nodeValue.charAt( 0 ) != '\n' |
| 431 | + && t.node.nodeValue.charAt( 0 ) != '\r' ) { |
| 432 | + text += "\n"; |
| 433 | + } |
| 434 | + $( this ).text( text ); |
| 435 | + } |
| 436 | + } ); |
| 437 | + var retval; |
| 438 | + if ( $.browser.msie ) { |
| 439 | + // IE aggressively collapses whitespace in .text() after having done DOM manipulation, |
| 440 | + // but for some crazy reason this does work. Also convert \r back to \n |
| 441 | + retval = $( '<pre>' + $pre.html() + '</pre>' ).text().replace( /\r/g, '\n' ); |
| 442 | + } else { |
| 443 | + retval = $pre.text(); |
| 444 | + } |
| 445 | + return context.htmlToTextMap[origHTML] = leading + retval + trailing; |
380 | 446 | }, |
381 | 447 | |
382 | 448 | /* |
— | — | @@ -400,6 +466,17 @@ |
401 | 467 | if ( context.$iframe[0].contentWindow.getSelection ) { |
402 | 468 | // Firefox and Opera |
403 | 469 | retval = context.$iframe[0].contentWindow.getSelection(); |
| 470 | + if ( $.browser.opera ) { |
| 471 | + // Opera strips newlines in getSelection(), so we need something more sophisticated |
| 472 | + if ( retval.rangeCount > 0 ) { |
| 473 | + retval = context.fn.htmlToText( $( '<pre />' ) |
| 474 | + .append( retval.getRangeAt( 0 ).cloneContents() ) |
| 475 | + .html() |
| 476 | + ); |
| 477 | + } else { |
| 478 | + retval = ''; |
| 479 | + } |
| 480 | + } |
404 | 481 | } else if ( context.$iframe[0].contentWindow.document.selection ) { // should come last; Opera! |
405 | 482 | // IE |
406 | 483 | retval = context.$iframe[0].contentWindow.document.selection.createRange(); |
— | — | @@ -443,25 +520,47 @@ |
444 | 521 | // Firefox and Opera |
445 | 522 | var range = context.$iframe[0].contentWindow.getSelection().getRangeAt( 0 ); |
446 | 523 | if ( options.ownline ) { |
| 524 | + // We need to figure out if the cursor is at the start or end of a line |
| 525 | + var atStart = false, atEnd = false; |
447 | 526 | var body = context.$content.get( 0 ); |
448 | | - // TODO: This'll probably break with syntax highlighting |
449 | | - // When the selection starts at the beginning of a line, it'll have either |
450 | | - // startOffset == 0 or startContainer == body |
451 | | - if ( range.startOffset != 0 && range.startContainer != body ) { |
| 527 | + if ( range.startOffset == 0 ) { |
| 528 | + // Start of a line |
| 529 | + // FIXME: Not necessarily the case with syntax highlighting or |
| 530 | + // template collapsing |
| 531 | + atStart = true; |
| 532 | + } else if ( range.startContainer == body ) { |
| 533 | + // Look up the node just before the start of the selection |
| 534 | + // If it's a <BR>, we're at the start of a line that starts with a |
| 535 | + // block element; if not, we're at the end of a line |
| 536 | + var n = body.firstChild; |
| 537 | + for ( var i = 0; i < range.startOffset - 1 && n; i++ ) { |
| 538 | + n = n.nextSibling; |
| 539 | + } |
| 540 | + if ( n && n.nodeName == 'BR' ) { |
| 541 | + atStart = true; |
| 542 | + } else { |
| 543 | + atEnd = true; |
| 544 | + } |
| 545 | + } else if ( range.startContainer.nodeName == '#text' && |
| 546 | + range.startOffset == range.startContainer.nodeValue.length ) { |
| 547 | + // Apparently this happens when splitting text nodes |
| 548 | + atEnd = true; |
| 549 | + } |
| 550 | + |
| 551 | + if ( !atStart ) { |
452 | 552 | pre = "\n" + options.pre; |
453 | 553 | } |
454 | | - // TODO: Will this still work with syntax highlighting? |
455 | | - // When the selection ends at the end of a line, it'll have endContainer == body |
456 | | - // and endOffset != 0 |
457 | | - if ( range.endContainer != body || range.endOffset == 0 ) { |
| 554 | + if ( !atEnd ) { |
458 | 555 | post += "\n"; |
459 | 556 | } |
460 | 557 | } |
461 | 558 | var insertText = ""; |
462 | 559 | if ( options.splitlines ) { |
463 | | - for( var i = 0; i < selTextArr.length; i++ ) { |
464 | | - insertText = insertText + pre + selTextArr[i] + post; |
465 | | - if( i != selTextArr.length - 1 ) insertText += "\n"; |
| 560 | + for( var j = 0; j < selTextArr.length; j++ ) { |
| 561 | + insertText = insertText + pre + selTextArr[j] + post; |
| 562 | + if( j != selTextArr.length - 1 ) { |
| 563 | + insertText += "\n"; |
| 564 | + } |
466 | 565 | } |
467 | 566 | } else { |
468 | 567 | insertText = pre + selText + post; |
— | — | @@ -507,9 +606,9 @@ |
508 | 607 | // TODO: Clean this up. Duplicate code due to the pre-existing browser specific structure of this function |
509 | 608 | var insertText = ""; |
510 | 609 | if ( options.splitlines ) { |
511 | | - for( var i = 0; i < selTextArr.length; i++ ) { |
512 | | - insertText = insertText + pre + selTextArr[i] + post; |
513 | | - if( i != selTextArr.length - 1 ) { |
| 610 | + for( var j = 0; j < selTextArr.length; j++ ) { |
| 611 | + insertText = insertText + pre + selTextArr[j] + post; |
| 612 | + if( j != selTextArr.length - 1 ) { |
514 | 613 | insertText += "\n"; |
515 | 614 | } |
516 | 615 | } |
— | — | @@ -634,14 +733,14 @@ |
635 | 734 | */ |
636 | 735 | |
637 | 736 | /** |
638 | | - * Get the first element before the selection matching a certain selector. |
639 | | - * @param selector Selector to match. Defaults to '*' |
| 737 | + * Get the first element before the selection that's in a certain class |
| 738 | + * @param classname Class to match. Defaults to '', meaning any class |
640 | 739 | * @param strict If true, the element the selection starts in cannot match (default: false) |
641 | 740 | * @return jQuery object |
642 | 741 | */ |
643 | | - 'beforeSelection': function( selector, strict ) { |
644 | | - if ( typeof selector == 'undefined' ) { |
645 | | - selector = '*'; |
| 742 | + 'beforeSelection': function( classname, strict ) { |
| 743 | + if ( typeof classname == 'undefined' ) { |
| 744 | + classname = ''; |
646 | 745 | } |
647 | 746 | var e, offset; |
648 | 747 | if ( context.$iframe[0].contentWindow.getSelection ) { |
— | — | @@ -652,7 +751,7 @@ |
653 | 752 | // Start at the selection's start and traverse the DOM backwards |
654 | 753 | // This is done by traversing an element's children first, then the element itself, then its parent |
655 | 754 | e = selection.getRangeAt( 0 ).startContainer; |
656 | | - offset = selection.startOffset; |
| 755 | + offset = selection.getRangeAt( 0 ).startOffset; |
657 | 756 | } else { |
658 | 757 | return $( [] ); |
659 | 758 | } |
— | — | @@ -667,7 +766,7 @@ |
668 | 767 | // not in the iframe |
669 | 768 | try { |
670 | 769 | range2.setEndPoint( 'EndToStart', range ); |
671 | | - } catch ( e ) { |
| 770 | + } catch ( ex ) { |
672 | 771 | return $( [] ); |
673 | 772 | } |
674 | 773 | var seekPos = context.fn.htmlToText( range2.htmlText ).length; |
— | — | @@ -691,9 +790,14 @@ |
692 | 791 | } |
693 | 792 | e = newE || e; |
694 | 793 | } |
| 794 | + |
| 795 | + // We'd normally use if( $( e ).hasClass( class ) in the while loop, but running the jQuery |
| 796 | + // constructor thousands of times is very inefficient |
| 797 | + var classStr = ' ' + classname + ' '; |
695 | 798 | while ( e ) { |
696 | | - if ( $( e ).is( selector ) && !strict ) |
| 799 | + if ( !strict && ( !classname || ( ' ' + e.className + ' ' ).indexOf( classStr ) != -1 ) ) { |
697 | 800 | return $( e ); |
| 801 | + } |
698 | 802 | var next = e.previousSibling; |
699 | 803 | while ( next && next.lastChild ) { |
700 | 804 | next = next.lastChild; |
— | — | @@ -704,8 +808,88 @@ |
705 | 809 | return $( [] ); |
706 | 810 | }, |
707 | 811 | /** |
| 812 | + * Object used by traverser(). Don't use this unless you know what you're doing |
| 813 | + */ |
| 814 | + 'rawTraverser': function( node, depth, inP ) { |
| 815 | + this.node = node; |
| 816 | + this.depth = depth; |
| 817 | + this.inP = inP; |
| 818 | + this.next = function() { |
| 819 | + var p = this.node; |
| 820 | + var nextDepth = this.depth; |
| 821 | + var nextInP = this.inP; |
| 822 | + while ( p && !p.nextSibling ) { |
| 823 | + p = p.parentNode; |
| 824 | + nextDepth--; |
| 825 | + if ( nextDepth == 0 ) { |
| 826 | + // We're back at the start node |
| 827 | + p = null; |
| 828 | + } |
| 829 | + if ( p && p.nodeName == "P" ) { |
| 830 | + nextInP = null; |
| 831 | + } |
| 832 | + } |
| 833 | + p = p ? p.nextSibling : null; |
| 834 | + if ( p && p.nodeName == "P" ) { |
| 835 | + nextInP = p; |
| 836 | + } |
| 837 | + do { |
| 838 | + // Filter nodes with the wikiEditor-noinclude class |
| 839 | + // Don't use $( p ).hasClass( 'wikiEditor-noinclude' ) because |
| 840 | + // $() is slow in a tight loop |
| 841 | + while ( p && ( ' ' + p.className + ' ' ).indexOf( ' wikiEditor-noinclude ' ) != -1 ) { |
| 842 | + p = p.nextSibling; |
| 843 | + } |
| 844 | + if ( p && p.firstChild ) { |
| 845 | + p = p.firstChild; |
| 846 | + nextDepth++; |
| 847 | + if ( p.nodeName == "P" ) { |
| 848 | + nextInP = p; |
| 849 | + } |
| 850 | + } |
| 851 | + } while ( p && p.firstChild ); |
| 852 | + return p ? new context.fn.rawTraverser( p, nextDepth, nextInP ) : null; |
| 853 | + }; |
| 854 | + this.prev = function() { |
| 855 | + var p = this.node; |
| 856 | + var prevDepth = this.depth; |
| 857 | + var prevInP = this.inP; |
| 858 | + while ( p && !p.previousSibling ) { |
| 859 | + p = p.parentNode; |
| 860 | + prevDepth--; |
| 861 | + if ( prevDepth == 0 ) { |
| 862 | + // We're back at the start node |
| 863 | + p = null; |
| 864 | + } |
| 865 | + if ( p && p.nodeName == "P" ) { |
| 866 | + prevInP = null; |
| 867 | + } |
| 868 | + } |
| 869 | + p = p ? p.previousSibling : null; |
| 870 | + if ( p && p.nodeName == "P" ) { |
| 871 | + prevInP = p; |
| 872 | + } |
| 873 | + do { |
| 874 | + // Filter nodes with the wikiEditor-noinclude class |
| 875 | + // Don't use $( p ).hasClass( 'wikiEditor-noinclude' ) because |
| 876 | + // $() is slow in a tight loop |
| 877 | + while ( p && ( ' ' + p.className + ' ' ).indexOf( ' wikiEditor-noinclude ' ) != -1 ) { |
| 878 | + p = p.previousSibling; |
| 879 | + } |
| 880 | + if ( p && p.lastChild ) { |
| 881 | + p = p.lastChild; |
| 882 | + prevDepth++; |
| 883 | + if ( p.nodeName == "P" ) { |
| 884 | + prevInP = p; |
| 885 | + } |
| 886 | + } |
| 887 | + } while ( p && p.lastChild ); |
| 888 | + return p ? new context.fn.rawTraverser( p, prevDepth, prevInP ) : null; |
| 889 | + }; |
| 890 | + }, |
| 891 | + /** |
708 | 892 | * Get an object used to traverse the leaf nodes in the iframe DOM. This traversal skips leaf nodes |
709 | | - * inside an element with the wikiEditor-noinclude class. |
| 893 | + * inside an element with the wikiEditor-noinclude class. This basically wraps rawTraverser |
710 | 894 | * |
711 | 895 | * Usage: |
712 | 896 | * var t = context.fn.traverser( context.$content ); |
— | — | @@ -715,48 +899,10 @@ |
716 | 900 | * // Trying to advance past the end will set t.node to null |
717 | 901 | */ |
718 | 902 | 'traverser': function( start ) { |
719 | | - function Traverser( node, depth, inP ) { |
720 | | - this.node = node; |
721 | | - this.depth = depth; |
722 | | - this.inP = inP; |
723 | | - this.next = function() { |
724 | | - var p = this.node; |
725 | | - var nextDepth = this.depth; |
726 | | - var nextInP = this.inP; |
727 | | - while ( p && !p.nextSibling ) { |
728 | | - if ( p.nodeName == "P" ) { |
729 | | - nextInP = false; |
730 | | - } |
731 | | - p = p.parentNode; |
732 | | - nextDepth--; |
733 | | - if ( nextDepth == 0 ) { |
734 | | - // We're back at the start node |
735 | | - p = null; |
736 | | - } |
737 | | - } |
738 | | - p = p ? p.nextSibling : null; |
739 | | - do { |
740 | | - // Filter nodes with the wikiEditor-noinclude class |
741 | | - // Don't use $( p ).hasClass( 'wikiEditor-noinclude' ) because |
742 | | - // $() is slow in a tight loop |
743 | | - while ( p && ( ' ' + p.className + ' ' ).indexOf( ' wikiEditor-noinclude ' ) != -1 ) { |
744 | | - p = p.nextSibling; |
745 | | - } |
746 | | - if ( p && p.firstChild ) { |
747 | | - p = p.firstChild; |
748 | | - nextDepth++; |
749 | | - if ( p.nodeName == "P" ) { |
750 | | - nextInP = true; |
751 | | - } |
752 | | - } |
753 | | - } while ( p && p.firstChild ); |
754 | | - return p ? new Traverser( p, nextDepth, nextInP ) : null; |
755 | | - }; |
756 | | - } |
757 | 903 | // Find the leftmost leaf node in the tree |
758 | 904 | var node = start.jquery ? start.get( 0 ) : start; |
759 | 905 | var depth = 0; |
760 | | - var inP = node.nodeName == "P"; |
| 906 | + var inP = node.nodeName == "P" ? node : null; |
761 | 907 | do { |
762 | 908 | // Filter nodes with the wikiEditor-noinclude class |
763 | 909 | // Don't use $( p ).hasClass( 'wikiEditor-noinclude' ) because |
— | — | @@ -768,11 +914,11 @@ |
769 | 915 | node = node.firstChild; |
770 | 916 | depth++; |
771 | 917 | if ( node.nodeName == "P" ) { |
772 | | - inP = true; |
| 918 | + inP = node; |
773 | 919 | } |
774 | 920 | } |
775 | 921 | } while ( node && node.firstChild ); |
776 | | - return new Traverser( node, depth, inP ); |
| 922 | + return new context.fn.rawTraverser( node, depth, inP ); |
777 | 923 | }, |
778 | 924 | 'getOffset': function( offset ) { |
779 | 925 | if ( !context.offsets ) { |
— | — | @@ -796,7 +942,7 @@ |
797 | 943 | var base = context.offsets[lowerBound]; |
798 | 944 | return context.offsets[offset] = { |
799 | 945 | 'node': base.node, |
800 | | - 'offset': base.offset + offset - o, |
| 946 | + 'offset': base.offset + offset - lowerBound, |
801 | 947 | 'length': base.length, |
802 | 948 | 'depth': base.depth, |
803 | 949 | 'lastTextNode': base.lastTextNode, |
— | — | @@ -811,13 +957,13 @@ |
812 | 958 | var t = context.fn.traverser( context.$content ); |
813 | 959 | var pos = 0, lastTextNode = null, lastTextNodeDepth = null; |
814 | 960 | while ( t ) { |
815 | | - if ( t.node.nodeName != '#text' && t.node.nodeName != 'BR' ) { |
| 961 | + if ( t.node.nodeName != '#text' && t.node.nodeName != 'BR' && t.node.nodeName != 'P' ) { |
816 | 962 | t = t.next(); |
817 | 963 | continue; |
818 | 964 | } |
819 | 965 | var nextPos = t.node.nodeName == '#text' ? pos + t.node.nodeValue.length : pos + 1; |
820 | 966 | var nextT = t.next(); |
821 | | - var leavingP = t.inP && nextT && !nextT.inP; |
| 967 | + var leavingP = t.node.nodeName != 'P' && t.inP && nextT && ( !nextT.inP || nextT.inP != t.inP ); |
822 | 968 | context.offsets[pos] = { |
823 | 969 | 'node': t.node, |
824 | 970 | 'offset': 0, |
— | — | @@ -887,7 +1033,7 @@ |
888 | 1034 | // Setup the intial view |
889 | 1035 | context.view = 'wikitext'; |
890 | 1036 | // Trigger the "resize" event anytime the window is resized |
891 | | - $( window ).resize( function( event ) { context.fn.trigger( 'resize', event ) } ); |
| 1037 | + $( window ).resize( function( event ) { context.fn.trigger( 'resize', event ); } ); |
892 | 1038 | // Create an iframe in place of the text area |
893 | 1039 | context.$iframe = $( '<iframe></iframe>' ) |
894 | 1040 | .attr( { |
— | — | @@ -923,7 +1069,13 @@ |
924 | 1070 | // If we just do "context.$content.text( context.$textarea.val() )", Internet Explorer will strip out the |
925 | 1071 | // whitespace charcters, specifically "\n" - so we must manually encode the text and append it |
926 | 1072 | // TODO: Refactor this into a textToHtml() function |
927 | | - var html = context.$textarea.val(); |
| 1073 | + // Because we're gonna insert instances of <br>, and <span class="wikiEditor-tab"></span>, |
| 1074 | + // we have to escape existing instances first. This'll cause them to be double-escaped, which we |
| 1075 | + // fix later on |
| 1076 | + var html = context.$textarea.val() |
| 1077 | + .replace( / /g, '&nbsp;' ) |
| 1078 | + .replace( /\<br\>/g, '<br>' ) |
| 1079 | + .replace( /\<span class="wikiEditor-tab"\>\<\/span\>/g, '<span class="wikiEditor-tab"></span>' ); |
928 | 1080 | // We must do some extra processing on IE to avoid dirty diffs, specifically IE will collapse leading spaces |
929 | 1081 | if ( $.browser.msie ) { |
930 | 1082 | // Browser sniffing is not ideal, but executing this code on a non-broken browser doesn't cause harm |
— | — | @@ -939,11 +1091,20 @@ |
940 | 1092 | } |
941 | 1093 | // Use a dummy div to escape all entities |
942 | 1094 | // This'll also escape <br>, <span> and , so we unescape those after |
943 | | - html = $( '<div />' ).text( html.replace( /\r?\n/g, '<br>' ) ).html() |
| 1095 | + // We also need to unescape the doubly-escaped things mentioned above |
| 1096 | + html = $( '<div />' ).text( '<p>' + html.replace( /\r?\n/g, '</p><p>' ) + '</p>' ).html() |
944 | 1097 | .replace( /&nbsp;/g, ' ' ) |
945 | | - .replace( /<br>/g, '<br>' ) |
946 | | - .replace( /<span class="wikiEditor-tab"><\/span>/g, '<span class="wikiEditor-tab"></span>' ); |
| 1098 | + // Allow p tags to survive encoding |
| 1099 | + .replace( /<p>/g, '<p>' ) |
| 1100 | + .replace( /<\/p>/g, '</p>' ) |
| 1101 | + // Empty p tags should just be br tags |
| 1102 | + .replace( /<p><\/p>/g, '<br>' ) |
| 1103 | + .replace( /<span class="wikiEditor-tab"><\/span>/g, '<span class="wikiEditor-tab"></span>' ) |
| 1104 | + .replace( /&amp;nbsp;/g, '&nbsp;' ) |
| 1105 | + .replace( /&lt;br&gt;/g, '<br>' ) |
| 1106 | + .replace( /&lt;span class=&quot;wikiEditor-tab&quot;&gt;&lt;\/span&gt;/g, '<span class="wikiEditor-tab"></span>' ); |
947 | 1107 | context.$content.html( html ); |
| 1108 | + context.oldHTML = html; |
948 | 1109 | |
949 | 1110 | // Reflect direction of parent frame into child |
950 | 1111 | if ( $( 'body' ).is( '.rtl' ) ) { |
— | — | @@ -976,19 +1137,19 @@ |
977 | 1138 | window.onbeforeunload = function() { |
978 | 1139 | context.$textarea.val( context.$textarea.textSelection( 'getContents' ) ); |
979 | 1140 | return context.fallbackWindowOnBeforeUnload ? context.fallbackWindowOnBeforeUnload() : null; |
980 | | - } |
| 1141 | + }; |
981 | 1142 | } |
982 | 1143 | |
983 | 1144 | /* API Execution */ |
984 | 1145 | |
985 | 1146 | // Since javascript gives arguments as an object, we need to convert them so they can be used more easily |
986 | | -arguments = $.makeArray( arguments ); |
| 1147 | +var args = $.makeArray( arguments ); |
987 | 1148 | // There would need to be some arguments if the API is being called |
988 | | -if ( arguments.length > 0 ) { |
| 1149 | +if ( args.length > 0 ) { |
989 | 1150 | // Handle API calls |
990 | | - var call = arguments.shift(); |
| 1151 | + var call = args.shift(); |
991 | 1152 | if ( call in context.api ) { |
992 | | - context.api[call]( context, typeof arguments[0] == 'undefined' ? {} : arguments[0] ); |
| 1153 | + context.api[call]( context, typeof args[0] == 'undefined' ? {} : args[0] ); |
993 | 1154 | } |
994 | 1155 | } |
995 | 1156 | |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/js/plugins/jquery.wikiEditor.toolbar.js |
— | — | @@ -109,7 +109,7 @@ |
110 | 110 | $( $.wikiEditor.modules.toolbar.fn.buildCharacter( data[type][character], actions ) ) |
111 | 111 | .click( function() { |
112 | 112 | $.wikiEditor.modules.toolbar.fn.doAction( $(this).parent().data( 'context' ), |
113 | | - $(this).parent().data( 'actions' )[$(this).attr( 'rel' )] ); |
| 113 | + $(this).parent().data( 'actions' )[$(this).attr( 'rel' )] ); |
114 | 114 | return false; |
115 | 115 | } ) |
116 | 116 | ); |
— | — | @@ -205,7 +205,7 @@ |
206 | 206 | doAction : function( context, action, source ) { |
207 | 207 | // Verify that this has been called from a source that's within the toolbar |
208 | 208 | // 'trackAction' defined in click tracking |
209 | | - if ($.trackAction != undefined && source.closest( '.wikiEditor-ui-toolbar' ).size() ) { |
| 209 | + if ( $.trackAction != undefined && source.closest( '.wikiEditor-ui-toolbar' ).size() ) { |
210 | 210 | // Build a unique id for this action by tracking the parent rel attributes up to the toolbar level |
211 | 211 | var rels = []; |
212 | 212 | var step = source; |
— | — | @@ -223,7 +223,7 @@ |
224 | 224 | } |
225 | 225 | rels.reverse(); |
226 | 226 | var id = rels.join( '.' ); |
227 | | - $.trackAction(id); |
| 227 | + $.trackAction( id ); |
228 | 228 | } |
229 | 229 | switch ( action.type ) { |
230 | 230 | case 'replace': |
— | — | @@ -249,6 +249,7 @@ |
250 | 250 | 'encapsulateSelection', |
251 | 251 | $.extend( {}, action.options, parts, { 'replace': action.type == 'replace' } ) |
252 | 252 | ); |
| 253 | + context.$iframe[0].contentWindow.focus(); |
253 | 254 | break; |
254 | 255 | case 'callback': |
255 | 256 | if ( typeof action.execute == 'function' ) { |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/js/plugins/jquery.wikiEditor.highlight.js |
— | — | @@ -34,7 +34,7 @@ |
35 | 35 | * ; Definition |
36 | 36 | * : Definition |
37 | 37 | */ |
38 | | - if ( event.data.scope == 'division' ) { |
| 38 | + if ( event.data.scope == 'realchange' ) { |
39 | 39 | $.wikiEditor.modules.highlight.fn.scan( context, "" ); |
40 | 40 | $.wikiEditor.modules.highlight.fn.mark( context, "", "" ); |
41 | 41 | } |
— | — | @@ -55,7 +55,7 @@ |
56 | 56 | * @param config Configuration object to create module from |
57 | 57 | */ |
58 | 58 | create: function( context, config ) { |
59 | | - // hook $.wikiEditor.modules.highlight.evt.change to context.evt.change |
| 59 | + context.modules.highlight.markersStr = ''; |
60 | 60 | }, |
61 | 61 | /** |
62 | 62 | * Divides text into divisions |
— | — | @@ -144,6 +144,7 @@ |
145 | 145 | * @param tokens |
146 | 146 | */ |
147 | 147 | // FIXME: What do division and tokens do? |
| 148 | + // TODO: Document the scan() and mark() APIs somewhere |
148 | 149 | mark: function( context, division, tokens ) { |
149 | 150 | // Reset markers |
150 | 151 | var markers = context.modules.highlight.markers = []; |
— | — | @@ -151,7 +152,21 @@ |
152 | 153 | context.fn.trigger( 'mark' ); |
153 | 154 | markers.sort( function( a, b ) { return a.start - b.start || a.end - b.end; } ); |
154 | 155 | |
| 156 | + // Serialize the markers array to a string and compare it with the one stored in the previous run |
| 157 | + // If they're equal, there's no markers to change |
| 158 | + var markersStr = ''; |
| 159 | + for ( var i = 0; i < markers.length; i++ ) { |
| 160 | + markersStr += markers[i].start + ',' + markers[i].end + ',' + markers[i].type + ','; |
| 161 | + } |
| 162 | + if ( context.modules.highlight.markersStr == markersStr ) { |
| 163 | + // No change, bail out |
| 164 | + return; |
| 165 | + } |
| 166 | + context.modules.highlight.markersStr = markersStr; |
| 167 | + |
155 | 168 | // Traverse the iframe DOM, inserting markers where they're needed. |
| 169 | + // Store visited markers here so we know which markers should be removed |
| 170 | + var visited = []; |
156 | 171 | for ( var i = 0; i < markers.length; i++ ) { |
157 | 172 | // We want to isolate each marker, so we may need to split textNodes |
158 | 173 | // if a marker starts or ends halfway one. |
— | — | @@ -163,23 +178,27 @@ |
164 | 179 | } |
165 | 180 | var startNode = s.node; |
166 | 181 | var startDepth = s.depth; |
167 | | - // The next marker starts somewhere in this textNode or at this BR |
168 | | - if ( s.offset > 0 ) { |
169 | | - // t.node must be a textnode at this point because |
170 | | - // only textnodes can have offset > 0 |
171 | | - |
172 | | - // Split off the prefix |
173 | | - // This leaves the prefix in the current node and puts |
174 | | - // the rest in a new node which is our start node |
175 | | - startNode = startNode.splitText( s.offset ); |
176 | | - } |
| 182 | + |
177 | 183 | // Don't wrap leading BRs, produces undesirable results |
178 | | - while ( startNode.nodeName == 'BR' ) { |
| 184 | + // FIXME: It's also possible that the offset is a bit high because getOffset() has incremented |
| 185 | + // .length to fake the newline caused by startNode being in a P. In this case, prevent |
| 186 | + // the textnode splitting below from making startNode an empty textnode, IE barfs on that |
| 187 | + while ( startNode.nodeName == 'BR' || s.offset == startNode.nodeValue.length ) { |
179 | 188 | start++; |
180 | 189 | s = context.fn.getOffset( start ); |
181 | 190 | startNode = s.node; |
182 | 191 | startDepth = s.depth; |
183 | 192 | } |
| 193 | + |
| 194 | + // The next marker starts somewhere in this textNode or at this BR |
| 195 | + if ( s.offset > 0 && s.node.nodeName == '#text' ) { |
| 196 | + // Split off the prefix |
| 197 | + // This leaves the prefix in the current node and puts |
| 198 | + // the rest in a new node which is our start node |
| 199 | + startNode = startNode.splitText( s.offset ); |
| 200 | + // This also invalidates cached offset objects |
| 201 | + context.fn.purgeOffsets(); // TODO: Optimize better, get end offset object earlier |
| 202 | + } |
184 | 203 | |
185 | 204 | var end = markers[i].end; |
186 | 205 | var e = context.fn.getOffset( end ); |
— | — | @@ -189,14 +208,13 @@ |
190 | 209 | } |
191 | 210 | var endNode = e.node; |
192 | 211 | var endDepth = e.depth; |
193 | | - if ( e.offset < e.length - 1 ) { |
194 | | - // t.node must be a textnode at this point because |
195 | | - // .length is 1 for BRs and offset can't be < 0 |
196 | | - |
| 212 | + if ( e.offset < e.length - 1 && e.node.nodeName == '#text' ) { |
197 | 213 | // Split off the suffix - This puts the suffix in a new node and leaves the rest in the current |
198 | 214 | // node. |
199 | 215 | // endNode.nodeValue.length - ( newPos - markers[i].end ) |
200 | 216 | endNode.splitText( e.offset + 1 ); |
| 217 | + // This also invalidates cached offset objects |
| 218 | + context.fn.purgeOffsets(); // TODO: Optimize better, get end offset object earlier |
201 | 219 | } |
202 | 220 | |
203 | 221 | // Don't wrap trailing BRs, doing that causes weird issues |
— | — | @@ -236,13 +254,19 @@ |
237 | 255 | ca1 = ca1.parentNode.firstChild == ca1 ? ca1.parentNode : null; |
238 | 256 | ca2 = ca2.parentNode.lastChild == ca2 ? ca2.parentNode : null; |
239 | 257 | } |
240 | | - if ( ca1 && ca2 && ca1.parentNode && ca2.nextSibling ) { |
| 258 | + if ( ca1 && ca2 && ca1.parentNode ) { |
241 | 259 | var anchor = markers[i].getAnchor( ca1, ca2 ); |
242 | 260 | if ( !anchor ) { |
243 | 261 | // We have to store things like .parentNode and .nextSibling because appendChild() changes these |
244 | 262 | // properties |
245 | 263 | var newNode = ca1.ownerDocument.createElement( 'div' ); |
246 | 264 | var commonAncestor = ca1.parentNode; |
| 265 | + // Special case: can't put block elements in a <p> |
| 266 | + if ( commonAncestor.nodeName == 'P' && commonAncestor.parentNode ) { |
| 267 | + commonAncestor = commonAncestor.parentNode; |
| 268 | + ca1 = ca1.parentNode; |
| 269 | + ca2 = ca2.parentNode; |
| 270 | + } |
247 | 271 | var nextNode = ca2.nextSibling; |
248 | 272 | if ( markers[i].anchor == 'wrap' ) { |
249 | 273 | // Append all nodes between ca1 and ca2 (inclusive) to newNode |
— | — | @@ -269,22 +293,32 @@ |
270 | 294 | } |
271 | 295 | |
272 | 296 | $( newNode ).data( 'marker', markers[i] ) |
273 | | - .addClass( 'wikiEditor-highlight wikiEditor-highlight-tmp' ); |
| 297 | + .addClass( 'wikiEditor-highlight' ); |
| 298 | + visited[i] = newNode; |
274 | 299 | |
275 | 300 | // Allow the module adding this marker to manipulate it |
276 | 301 | markers[i].afterWrap( newNode, markers[i] ); |
277 | 302 | } else { |
278 | | - // Temporarily add a class for bookkeeping purposes |
279 | | - $( anchor ) |
280 | | - .addClass( 'wikiEditor-highlight-tmp' ) |
281 | | - .data( 'marker', markers[i] ); |
| 303 | + visited[i] = anchor; |
| 304 | + // Update the marker object |
| 305 | + $( anchor ).data( 'marker', markers[i] ); |
282 | 306 | markers[i].onSkip( anchor ); |
283 | 307 | } |
284 | 308 | } |
285 | 309 | } |
286 | 310 | |
287 | 311 | // Remove markers that were previously inserted but weren't passed to this function |
288 | | - context.$content.find( 'div.wikiEditor-highlight:not(.wikiEditor-highlight-tmp)' ).each( function() { |
| 312 | + // This function works because visited[] contains the visited elements in order and find() and each() |
| 313 | + // preserve order |
| 314 | + var j = 0; |
| 315 | + context.$content.find( 'div.wikiEditor-highlight' ).each( function() { |
| 316 | + if ( visited[j] == this ) { |
| 317 | + // This marker is legit, leave it in |
| 318 | + j++; |
| 319 | + return true; |
| 320 | + } |
| 321 | + |
| 322 | + // Remove this marker |
289 | 323 | if ( $(this).data( 'marker' ) && typeof $(this).data( 'marker' ).unwrap == 'function' ) |
290 | 324 | $(this).data( 'marker' ).unwrap( this ); |
291 | 325 | if ( $(this).children().size() > 0 ) { |
— | — | @@ -293,8 +327,6 @@ |
294 | 328 | $(this).replaceWith( $(this).html() ); |
295 | 329 | } |
296 | 330 | }); |
297 | | - // Remove temporary class |
298 | | - context.$content.find( 'div.wikiEditor-highlight-tmp' ).removeClass( 'wikiEditor-highlight-tmp' ); |
299 | 331 | } |
300 | 332 | } |
301 | 333 | |
Index: branches/wmf-deployment/extensions/UsabilityInitiative_alpha/UsabilityInitiative.hooks.php |
— | — | @@ -21,19 +21,19 @@ |
22 | 22 | array( 'src' => 'css/suggestions.css', 'version' => 6 ), |
23 | 23 | array( 'src' => 'css/vector.collapsibleNav.css', 'version' => 7 ), |
24 | 24 | array( 'src' => 'css/vector.footerCleanup.css', 'version' => 1 ), |
25 | | - array( 'src' => 'css/wikiEditor.css', 'version' => 8 ), |
26 | | - array( 'src' => 'css/wikiEditor.dialogs.css', 'version' => 15 ), |
| 25 | + array( 'src' => 'css/wikiEditor.css', 'version' => 9 ), |
| 26 | + array( 'src' => 'css/wikiEditor.dialogs.css', 'version' => 16 ), |
27 | 27 | array( 'src' => 'css/wikiEditor.preview.css', 'version' => 1 ), |
28 | 28 | array( 'src' => 'css/wikiEditor.toc.css', 'version' => 28 ), |
29 | 29 | array( 'src' => 'css/wikiEditor.toolbar.css', 'version' => 10 ), |
30 | 30 | array( 'src' => 'css/vector/jquery-ui-1.7.2.css', 'version' => '1.7.2y' ), |
31 | 31 | ), |
32 | 32 | 'combined' => array( |
33 | | - array( 'src' => 'css/combined.css', 'version' => 58 ), |
| 33 | + array( 'src' => 'css/combined.css', 'version' => 60 ), |
34 | 34 | array( 'src' => 'css/vector/jquery-ui-1.7.2.css', 'version' => '1.7.2y' ), |
35 | 35 | ), |
36 | 36 | 'minified' => array( |
37 | | - array( 'src' => 'css/combined.min.css', 'version' => 58 ), |
| 37 | + array( 'src' => 'css/combined.min.css', 'version' => 60 ), |
38 | 38 | array( 'src' => 'css/vector/jquery-ui-1.7.2.css', 'version' => '1.7.2y' ), |
39 | 39 | ), |
40 | 40 | ) |
— | — | @@ -72,20 +72,20 @@ |
73 | 73 | array( 'src' => 'js/plugins/jquery.namespaceSelect.js', 'version' => 1 ), |
74 | 74 | array( 'src' => 'js/plugins/jquery.suggestions.js', 'version' => 7 ), |
75 | 75 | array( 'src' => 'js/plugins/jquery.textSelection.js', 'version' => 26 ), |
76 | | - array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 77 ), |
77 | | - array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 25 ), |
78 | | - array( 'src' => 'js/plugins/jquery.wikiEditor.toolbar.js', 'version' => 45 ), |
| 76 | + array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 94 ), |
| 77 | + array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 29 ), |
| 78 | + array( 'src' => 'js/plugins/jquery.wikiEditor.toolbar.js', 'version' => 46 ), |
79 | 79 | array( 'src' => 'js/plugins/jquery.wikiEditor.dialogs.js', 'version' => 11 ), |
80 | | - array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 74 ), |
| 80 | + array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 78 ), |
81 | 81 | array( 'src' => 'js/plugins/jquery.wikiEditor.preview.js', 'version' => 10 ), |
82 | | - array( 'src' => 'js/plugins/jquery.wikiEditor.templateEditor.js', 'version' => 16 ), |
| 82 | + array( 'src' => 'js/plugins/jquery.wikiEditor.templateEditor.js', 'version' => 17 ), |
83 | 83 | array( 'src' => 'js/plugins/jquery.wikiEditor.publish.js', 'version' => 2 ), |
84 | 84 | ), |
85 | 85 | 'combined' => array( |
86 | | - array( 'src' => 'js/plugins.combined.js', 'version' => 189 ), |
| 86 | + array( 'src' => 'js/plugins.combined.js', 'version' => 211 ), |
87 | 87 | ), |
88 | 88 | 'minified' => array( |
89 | | - array( 'src' => 'js/plugins.combined.min.js', 'version' => 189 ), |
| 89 | + array( 'src' => 'js/plugins.combined.min.js', 'version' => 211 ), |
90 | 90 | ), |
91 | 91 | ), |
92 | 92 | ); |