summaryrefslogtreecommitdiffstats
path: root/skins/common/edit.js
diff options
context:
space:
mode:
Diffstat (limited to 'skins/common/edit.js')
-rw-r--r--skins/common/edit.js231
1 files changed, 231 insertions, 0 deletions
diff --git a/skins/common/edit.js b/skins/common/edit.js
new file mode 100644
index 0000000..423205f
--- /dev/null
+++ b/skins/common/edit.js
@@ -0,0 +1,231 @@
+var currentFocused;
+
+// this function generates the actual toolbar buttons with localized text
+// we use it to avoid creating the toolbar where javascript is not enabled
+function addButton( imageFile, speedTip, tagOpen, tagClose, sampleText, imageId ) {
+ // Don't generate buttons for browsers which don't fully
+ // support it.
+ mwEditButtons.push({
+ 'imageId': imageId,
+ 'imageFile': imageFile,
+ 'speedTip': speedTip,
+ 'tagOpen': tagOpen,
+ 'tagClose': tagClose,
+ 'sampleText': sampleText
+ });
+}
+
+// this function generates the actual toolbar buttons with localized text
+// we use it to avoid creating the toolbar where JavaScript is not enabled
+function mwInsertEditButton( parent, item ) {
+ var image = document.createElement( 'img' );
+ image.width = 23;
+ image.height = 22;
+ image.className = 'mw-toolbar-editbutton';
+ if ( item.imageId ) {
+ image.id = item.imageId;
+ }
+ image.src = item.imageFile;
+ image.border = 0;
+ image.alt = item.speedTip;
+ image.title = item.speedTip;
+ image.style.cursor = 'pointer';
+ image.onclick = function() {
+ insertTags( item.tagOpen, item.tagClose, item.sampleText );
+ // click tracking
+ if ( ( typeof $j != 'undefined' ) && ( typeof $j.trackAction != 'undefined' ) ) {
+ $j.trackAction( 'oldedit.' + item.speedTip.replace(/ /g, "-") );
+ }
+ return false;
+ };
+
+ parent.appendChild( image );
+ return true;
+}
+
+function mwSetupToolbar() {
+ var toolbar = document.getElementById( 'toolbar' );
+ if ( !toolbar ) {
+ return false;
+ }
+
+ // Don't generate buttons for browsers which don't fully
+ // support it.
+ // but don't assume wpTextbox1 is always here
+ var textboxes = document.getElementsByTagName( 'textarea' );
+ if ( !textboxes.length ) {
+ // No toolbar if we can't find any textarea
+ return false;
+ }
+ // Only check for selection capability if the textarea is visible - errors will occur otherwise - just because
+ // the textarea is not visible, doesn't mean we shouldn't build out the toolbar though - it might have been replaced
+ // with some other kind of control
+ if ( textboxes[0].style.display != 'none' ) {
+ if ( !( document.selection && document.selection.createRange )
+ && textboxes[0].selectionStart === null ) {
+ return false;
+ }
+ }
+ for ( var i = 0; i < mwEditButtons.length; i++ ) {
+ mwInsertEditButton( toolbar, mwEditButtons[i] );
+ }
+ for ( var i = 0; i < mwCustomEditButtons.length; i++ ) {
+ mwInsertEditButton( toolbar, mwCustomEditButtons[i] );
+ }
+ return true;
+}
+
+// apply tagOpen/tagClose to selection in textarea,
+// use sampleText instead of selection if there is none
+function insertTags( tagOpen, tagClose, sampleText ) {
+ if ( typeof $j != 'undefined' && typeof $j.fn.textSelection != 'undefined' &&
+ ( currentFocused.nodeName.toLowerCase() == 'iframe' || currentFocused.id == 'wpTextbox1' ) ) {
+ $j( '#wpTextbox1' ).textSelection(
+ 'encapsulateSelection', { 'pre': tagOpen, 'peri': sampleText, 'post': tagClose }
+ );
+ return;
+ }
+ var txtarea;
+ if ( document.editform ) {
+ txtarea = currentFocused;
+ } else {
+ // some alternate form? take the first one we can find
+ var areas = document.getElementsByTagName( 'textarea' );
+ txtarea = areas[0];
+ }
+ var selText, isSample = false;
+
+ if ( document.selection && document.selection.createRange ) { // IE/Opera
+ // save window scroll position
+ if ( document.documentElement && document.documentElement.scrollTop ) {
+ var winScroll = document.documentElement.scrollTop
+ } else if ( document.body ) {
+ var winScroll = document.body.scrollTop;
+ }
+ // get current selection
+ txtarea.focus();
+ var range = document.selection.createRange();
+ selText = range.text;
+ // insert tags
+ checkSelectedText();
+ range.text = tagOpen + selText + tagClose;
+ // mark sample text as selected
+ if ( isSample && range.moveStart ) {
+ if ( window.opera ) {
+ tagClose = tagClose.replace(/\n/g,'');
+ }
+ range.moveStart('character', - tagClose.length - selText.length);
+ range.moveEnd('character', - tagClose.length);
+ }
+ range.select();
+ // restore window scroll position
+ if ( document.documentElement && document.documentElement.scrollTop ) {
+ document.documentElement.scrollTop = winScroll;
+ } else if ( document.body ) {
+ document.body.scrollTop = winScroll;
+ }
+
+ } else if ( txtarea.selectionStart || txtarea.selectionStart == '0' ) { // Mozilla
+ // save textarea scroll position
+ var textScroll = txtarea.scrollTop;
+ // get current selection
+ txtarea.focus();
+ var startPos = txtarea.selectionStart;
+ var endPos = txtarea.selectionEnd;
+ selText = txtarea.value.substring( startPos, endPos );
+ // insert tags
+ checkSelectedText();
+ txtarea.value = txtarea.value.substring(0, startPos)
+ + tagOpen + selText + tagClose
+ + txtarea.value.substring(endPos, txtarea.value.length);
+ // set new selection
+ if ( isSample ) {
+ txtarea.selectionStart = startPos + tagOpen.length;
+ txtarea.selectionEnd = startPos + tagOpen.length + selText.length;
+ } else {
+ txtarea.selectionStart = startPos + tagOpen.length + selText.length + tagClose.length;
+ txtarea.selectionEnd = txtarea.selectionStart;
+ }
+ // restore textarea scroll position
+ txtarea.scrollTop = textScroll;
+ }
+
+ function checkSelectedText() {
+ if ( !selText ) {
+ selText = sampleText;
+ isSample = true;
+ } else if ( selText.charAt(selText.length - 1) == ' ' ) { // exclude ending space char
+ selText = selText.substring(0, selText.length - 1);
+ tagClose += ' ';
+ }
+ }
+
+}
+
+/**
+ * Restore the edit box scroll state following a preview operation,
+ * and set up a form submission handler to remember this state
+ */
+function scrollEditBox() {
+ var editBox = document.getElementById( 'wpTextbox1' );
+ var scrollTop = document.getElementById( 'wpScrolltop' );
+ var editForm = document.getElementById( 'editform' );
+ if( editForm && editBox && scrollTop ) {
+ if( scrollTop.value ) {
+ editBox.scrollTop = scrollTop.value;
+ }
+ addHandler( editForm, 'submit', function() {
+ scrollTop.value = editBox.scrollTop;
+ } );
+ }
+}
+hookEvent( 'load', scrollEditBox );
+hookEvent( 'load', mwSetupToolbar );
+hookEvent( 'load', function() {
+ currentFocused = document.getElementById( 'wpTextbox1' );
+ // http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
+ // focus does not bubble normally, but using a trick we can do event delegation
+ // on the focus event on all text inputs to make the toolbox usable on all of them
+ var editForm = document.getElementById( 'editform' );
+ if ( !editForm ) {
+ return;
+ }
+ function onfocus( e ) {
+ var elm = e.target || e.srcElement;
+ if ( !elm ) {
+ return;
+ }
+ var tagName = elm.tagName.toLowerCase();
+ var type = elm.type || '';
+ if ( tagName !== 'textarea' && tagName !== 'input' ) {
+ return;
+ }
+ if ( tagName === 'input' && type.toLowerCase() !== 'text' ) {
+ return;
+ }
+
+ currentFocused = elm;
+ }
+
+ if ( editForm.addEventListener ) {
+ // Gecko, WebKit, Opera, etc... (all standards compliant browsers)
+ editForm.addEventListener( 'focus', onfocus, true ); // This MUST be true to work
+ } else if ( editForm.attachEvent ) {
+ // IE needs a specific trick here since it doesn't support the standard
+ editForm.attachEvent( 'onfocusin', function() { onfocus( event ); } );
+ }
+
+ // HACK: make currentFocused work with the usability iframe
+ // With proper focus detection support (HTML 5!) this'll be much cleaner
+ if ( typeof $j != 'undefined' ) {
+ var iframe = $j( '.wikiEditor-ui-text iframe' );
+ if ( iframe.length > 0 ) {
+ $j( iframe.get( 0 ).contentWindow.document )
+ .add( iframe.get( 0 ).contentWindow.document.body ) // for IE
+ .focus( function() { currentFocused = iframe.get( 0 ); } );
+ }
+ }
+
+ editForm
+} );
+