Index: branches/js2-work/phase3/js/mwEmbed/modules/UploadWizard/mw.UploadWizard.js |
— | — | @@ -3,7 +3,7 @@ |
4 | 4 | "mwe-upwiz-tab-details": "2. Add licenses and descriptions", |
5 | 5 | "mwe-upwiz-tab-thanks": "3. Use your files", |
6 | 6 | "mwe-upwiz-intro": "Introductory text (short)", |
7 | | - "mwe-upwiz-select-files": "Select files:", |
| 7 | + //"mwe-upwiz-select-files": "Select files:", |
8 | 8 | "mwe-upwiz-add-file-n": "Add another file", |
9 | 9 | "mwe-upwiz-add-file-0": "Add a file", |
10 | 10 | "mwe-upwiz-browse": "Browse...", |
— | — | @@ -277,7 +277,7 @@ |
278 | 278 | * 'new' 'transporting' 'transported' 'details' 'submitting-details' 'complete' |
279 | 279 | * should fork this into two -- local and remote, e.g. filename |
280 | 280 | */ |
281 | | -mw.UploadWizardUpload = function() { |
| 281 | +mw.UploadWizardUpload = function( filesDiv ) { |
282 | 282 | var _this = this; |
283 | 283 | _this.state = 'new'; |
284 | 284 | _this.transportWeight = 1; // default |
— | — | @@ -292,7 +292,7 @@ |
293 | 293 | |
294 | 294 | // details |
295 | 295 | _this.details = new mw.UploadWizardDetails( _this, $j( '#mwe-upwiz-macro-files' )); |
296 | | - _this.ui = new mw.UploadWizardUploadInterface( _this ); |
| 296 | + _this.ui = new mw.UploadWizardUploadInterface( _this, filesDiv ); |
297 | 297 | |
298 | 298 | // handler -- usually ApiUploadHandler |
299 | 299 | // _this.handler = new ( mw.getConfig( 'uploadHandlerClass' ) )( _this ); |
— | — | @@ -489,54 +489,72 @@ |
490 | 490 | /** |
491 | 491 | * Create an interface fragment corresponding to a file input, suitable for Upload Wizard. |
492 | 492 | * @param upload |
| 493 | + * @param div to insert file interface |
| 494 | + * @param addInterface interface to add a new one (assumed that we start out there) |
493 | 495 | */ |
494 | | -mw.UploadWizardUploadInterface = function( upload ) { |
| 496 | +mw.UploadWizardUploadInterface = function( upload, filesDiv ) { |
495 | 497 | var _this = this; |
496 | 498 | |
497 | 499 | _this.upload = upload; |
498 | 500 | |
499 | 501 | // may need to collaborate with the particular upload type sometimes |
500 | 502 | // for the interface, as well as the uploadwizard. OY. |
501 | | - _this.div = $j('<div></div>').get(0); |
| 503 | + _this.div = $j('<div class="mwe-upwiz-file"></div>').get(0); |
| 504 | + _this.isFilled = false; |
502 | 505 | |
503 | | - _this.fileInputCtrl = $j('<input size=40 class="mwe-upwiz-file" name="file" type="file"/>').get(0); |
| 506 | + _this.fileInputCtrl = $j('<input size="1" class="mwe-upwiz-file-input" name="file" type="file"/>') |
| 507 | + .change( function() { _this.fileChanged() } ) |
| 508 | + .get(0); |
504 | 509 | |
| 510 | + |
505 | 511 | // XXX better class for helper, we probably have a standard already |
506 | | - _this.visibleFilename = $j('<div class="mwe-upwiz-visible-file helper">' + gM('mwe-upwiz-click-here') + '</div>'); |
| 512 | + _this.visibleFilename = $j('<div class="mwe-upwiz-visible-file"></div>').hide(); |
507 | 513 | |
508 | 514 | // XXX not sure if we will have a filename here -- we may want to autogenerate a "stashed" filename, |
509 | 515 | // with this flow |
510 | 516 | _this.filenameCtrl = $j('<input type="hidden" name="filename" value=""/>').get(0); |
511 | | - |
| 517 | + |
| 518 | + _this.fileCtrlContainer = $j('<div class="mwe-upwiz-file-ctrl-container">') |
| 519 | + // the css trickery (along with css) |
| 520 | + // here creates a giant size file input control which is contained within a div and then |
| 521 | + // clipped for overflow. The effect is that we have a div (ctrl-container) we can position anywhere |
| 522 | + // which works as a file input. It will be set to opacity:0 and then we can do whatever we want with |
| 523 | + // interface "below". |
| 524 | + // XXX caution -- if the add file input changes size we won't match, unless we add some sort of event to catch this. |
512 | 525 | _this.form = $j('<form class="mwe-upwiz-form"></form>') |
513 | | - .append($j('<div class="mwe-upwiz-file-ctrl-container">') |
514 | | - .append( _this.fileInputCtrl ) |
515 | | - .append( _this.visibleFilename ) |
516 | | - ).append( _this.filenameCtrl ).get( 0 ); |
| 526 | + .append( _this.visibleFilename ) |
| 527 | + .append( _this.fileCtrlContainer |
| 528 | + .append( _this.fileInputCtrl ) |
| 529 | + ) |
| 530 | + .append( _this.filenameCtrl ).get( 0 ); |
517 | 531 | |
518 | 532 | _this.progressMessage = $j('<span class="mwe-upwiz-status-message" style="display: none"></span>').get(0); |
519 | 533 | |
520 | | - $j( _this.fileInputCtrl ).change( function() { _this.fileChanged() } ); |
521 | 534 | |
522 | 535 | _this.errorDiv = $j('<div class="mwe-upwiz-upload-error" style="display: none;"></div>').get(0); |
523 | 536 | |
524 | 537 | _this.removeCtrl = $j( '<a title="' + gM( 'mwe-upwiz-remove-upload' ) |
525 | 538 | + '" href="#" class="mwe-upwiz-remove">x</a>' ) |
526 | 539 | .click( function() { _this.upload.remove() } ) |
| 540 | + .hide() |
527 | 541 | .get( 0 ); |
528 | 542 | |
529 | 543 | |
530 | | - |
531 | 544 | $j( _this.div ).append( _this.form ) |
532 | 545 | .append( _this.progressMessage ) |
533 | 546 | .append( _this.errorDiv ) |
534 | | - .append( _this.removeCtrl ); |
| 547 | + .append( _this.removeCtrl ) |
535 | 548 | |
| 549 | + // XXX evil hardcoded |
| 550 | + // we don't really need filesdiv if we do it this way? |
| 551 | + $j( _this.div ).insertBefore( '#mwe-upwiz-add-file' ); // append( _this.div ); |
| 552 | + |
536 | 553 | // _this.progressBar = ( no progress bar for individual uploads yet ) |
537 | 554 | // add a details thing to details |
538 | 555 | // this should bind only to the FIRST transportProgress |
539 | 556 | $j( upload ).bind( 'transportProgress', function(e) { _this.showTransportProgress(); e.stopPropagation() } ); |
540 | 557 | $j( upload ).bind( 'transported', function(e) { _this.showTransported(); e.stopPropagation(); } ); |
| 558 | + |
541 | 559 | }; |
542 | 560 | |
543 | 561 | |
— | — | @@ -608,6 +626,39 @@ |
609 | 627 | }, |
610 | 628 | |
611 | 629 | /** |
| 630 | + * Move the file input to cover a certain element on the page. |
| 631 | + * We use invisible file inputs because this is the only way to style a file input |
| 632 | + * or otherwise get it to do what you want. |
| 633 | + * It is helpful to sometimes move them to cover certain elements on the page, and |
| 634 | + * even to pass events like hover |
| 635 | + * @param selector jquery-compatible selector, for a single element |
| 636 | + */ |
| 637 | + moveFileInputToCover: function( selector ) { |
| 638 | + var _this = this; |
| 639 | + |
| 640 | + var $covered = $j( selector ); |
| 641 | + |
| 642 | + _this.fileCtrlContainer |
| 643 | + .css( $covered.position() ) |
| 644 | + .width( $covered.outerWidth() ) |
| 645 | + .height( $covered.outerHeight() ); |
| 646 | + |
| 647 | + // shift the file input over with negative margins, |
| 648 | + // internal to the overflow-containing div, so the div shows all button |
| 649 | + // and none of the textfield-like input |
| 650 | + $j( _this.fileInputCtrl ).css( { |
| 651 | + 'margin-left': '-' + ~~( $j( _this.fileInputCtrl).width() - $covered.outerWidth() - 10 ) + 'px', |
| 652 | + 'margin-top' : '-' + ~~( $j( _this.fileInputCtrl).height() - $covered.outerHeight() - 10 ) + 'px' |
| 653 | + } ); |
| 654 | + |
| 655 | + // pass hover events to the thing we cover, for interface niceties |
| 656 | + $j( _this.fileCtrlContainer ).bind( 'mouseenter mouseleave', function() { |
| 657 | + $j( selector ).toggleClass( 'hover' ); |
| 658 | + } ); |
| 659 | + |
| 660 | + }, |
| 661 | + |
| 662 | + /** |
612 | 663 | * this does two things: |
613 | 664 | * 1 ) since the file input has been hidden with some clever CSS ( to avoid x-browser styling issues ), |
614 | 665 | * update the visible filename |
— | — | @@ -632,7 +683,20 @@ |
633 | 684 | // this is a hack to get a filename guaranteed unique. |
634 | 685 | uniqueFilename = mw.getConfig( 'userName' ) + "_" + ( new Date() ).getTime() + "_" + filename; |
635 | 686 | $j( _this.filenameCtrl ).attr( 'value', uniqueFilename ); |
636 | | - $j( _this.upload ).trigger( 'filenameAccepted' ); |
| 687 | + |
| 688 | + if ( ! _this.isFilled ) { |
| 689 | + _this.isFilled = true; |
| 690 | + $j( _this.visibleFilename ).show(); |
| 691 | + $j( _this.removeCtrl ).show(); |
| 692 | + $j(_this.div ).css( { |
| 693 | + 'position': 'relative', // own our own file input; it will move with us now. |
| 694 | + 'height': '24px' |
| 695 | + } ); |
| 696 | + _this.moveFileInputToCover( _this.visibleFilename ); |
| 697 | + $j( _this.upload ).trigger( 'filled' ); |
| 698 | + } else { |
| 699 | + $j( _this.upload ).trigger( 'filenameAccepted' ); |
| 700 | + } |
637 | 701 | }, |
638 | 702 | |
639 | 703 | /** |
— | — | @@ -1657,9 +1721,9 @@ |
1658 | 1722 | + '<div id="mwe-upwiz-content">' |
1659 | 1723 | + '<div id="mwe-upwiz-tabdiv-file">' |
1660 | 1724 | + '<div id="mwe-upwiz-intro">' + gM('mwe-upwiz-intro') + '</div>' |
1661 | | - + '<div id="mwe-upwiz-select-files">' + gM('mwe-upwiz-select-files') + '</div>' |
1662 | | - + '<div id="mwe-upwiz-files"></div>' |
1663 | | - + '<div><a id="mwe-upwiz-add-file">' + gM("mwe-upwiz-add-file-0") + '</a></div>' |
| 1725 | + + '<div id="mwe-upwiz-files">' |
| 1726 | + + '<a id="mwe-upwiz-add-file">' + gM("mwe-upwiz-add-file-0") + '</a>' |
| 1727 | + + '</div>' |
1664 | 1728 | + '<div><button id="mwe-upwiz-upload-ctrl" disabled="disabled">' + gM("mwe-upwiz-upload") + '</button></div>' |
1665 | 1729 | + '<div id="mwe-upwiz-progress"></div>' |
1666 | 1730 | + '<div style="clear: left;"></div>' |
— | — | @@ -1711,7 +1775,7 @@ |
1712 | 1776 | // within FILE tab div |
1713 | 1777 | // select files: |
1714 | 1778 | // place for file interfaces |
1715 | | - $j('#mwe-upwiz-add-file').click( function() { _this.addUpload() } ); |
| 1779 | + // $j('#mwe-upwiz-add-file').click( function() { _this.newUpload() } ); |
1716 | 1780 | $j('#mwe-upwiz-upload-ctrl').click( function() { _this.startUploads() } ); |
1717 | 1781 | |
1718 | 1782 | _this.setupDeedOwnWork(); |
— | — | @@ -1740,7 +1804,7 @@ |
1741 | 1805 | |
1742 | 1806 | |
1743 | 1807 | // add one to start |
1744 | | - _this.addUpload(); |
| 1808 | + _this.newUpload( '#mwe-upwiz-add-file' ); |
1745 | 1809 | |
1746 | 1810 | // "select" the first tab - highlight, make it visible, hide all others |
1747 | 1811 | _this.moveToTab('file'); |
— | — | @@ -1786,25 +1850,27 @@ |
1787 | 1851 | * Finally stuff it into an array of uploads. |
1788 | 1852 | * @return boolean success |
1789 | 1853 | */ |
1790 | | - addUpload: function() { |
| 1854 | + newUpload: function() { |
1791 | 1855 | var _this = this; |
1792 | 1856 | if ( _this.uploads.length == _this.maxUploads ) { |
1793 | 1857 | return false; |
1794 | 1858 | } |
1795 | 1859 | |
1796 | | - var upload = new mw.UploadWizardUpload(); |
| 1860 | + var upload = new mw.UploadWizardUpload( _this, '#mwe-upwiz-files' ); |
| 1861 | + _this.uploadToAdd = upload; |
| 1862 | + |
| 1863 | + upload.ui.moveFileInputToCover( '#mwe-upwiz-add-file' ); |
1797 | 1864 | $j( upload ).bind( 'filenameAccepted', function(e) { _this.updateFileCounts(); e.stopPropagation(); } ); |
1798 | 1865 | $j( upload ).bind( 'removeUpload', function(e) { _this.removeUpload( upload ); e.stopPropagation(); } ); |
1799 | | - // this is only the UI one, so is the result even going to be there? |
| 1866 | + $j( upload ).bind( 'filled', function(e) { |
| 1867 | + _this.uploads.push( upload ); |
| 1868 | + _this.updateFileCounts(); |
| 1869 | + _this.newUpload(); |
| 1870 | + e.stopPropagation(); |
| 1871 | + } ); |
| 1872 | + // XXX bind to some error state |
1800 | 1873 | |
1801 | | - // bind to some error state |
1802 | | - |
1803 | | - _this.uploads.push( upload ); |
1804 | | - |
1805 | | - $j( "#mwe-upwiz-files" ).append( upload.ui.div ); |
1806 | | - |
1807 | | - _this.updateFileCounts(); |
1808 | | - |
| 1874 | + |
1809 | 1875 | return true; |
1810 | 1876 | }, |
1811 | 1877 | |
— | — | @@ -1812,6 +1878,9 @@ |
1813 | 1879 | * Remove an upload from our array of uploads, and the HTML UI |
1814 | 1880 | * We can remove the HTML UI directly, as jquery will just get the parent. |
1815 | 1881 | * We need to grep through the array of uploads, since we don't know the current index. |
| 1882 | + * We need to update file counts for obvious reasons. |
| 1883 | + * Finally, there is an uncounted upload, waiting to be used, which has a fileInput which covers the |
| 1884 | + * "add an upload" button. This is absolutely positioned, so it needs to be moved if another upload was removed. |
1816 | 1885 | * |
1817 | 1886 | * @param upload |
1818 | 1887 | */ |
— | — | @@ -1819,6 +1888,7 @@ |
1820 | 1889 | var _this = this; |
1821 | 1890 | mw.UploadWizardUtil.removeItem( _this.uploads, upload ); |
1822 | 1891 | _this.updateFileCounts(); |
| 1892 | + _this.uploadToAdd.ui.moveFileInputToCover( '#mwe-upwiz-add-file' ); |
1823 | 1893 | }, |
1824 | 1894 | |
1825 | 1895 | /** |
— | — | @@ -1948,14 +2018,19 @@ |
1949 | 2019 | |
1950 | 2020 | |
1951 | 2021 | /** |
1952 | | - * Occurs whenever we need to update the interface based on how many files are there or have transported |
1953 | | - * Also detects if all uploads have transported and kicks off the process that eventually gets us to Step 2. |
| 2022 | + * Occurs whenever we need to update the interface based on how many files there are |
1954 | 2023 | */ |
1955 | 2024 | updateFileCounts: function() { |
1956 | 2025 | var _this = this; |
1957 | 2026 | |
1958 | | - // Can we enable the "add an upload" button, and what should the text on the button show? |
1959 | 2027 | $j( '#mwe-upwiz-add-file' ).html( gM( 'mwe-upwiz-add-file-' + ( _this.uploads.length === 0 ? '0' : 'n' )) ); |
| 2028 | + |
| 2029 | + if ( _this.uploads.length ) { |
| 2030 | + $j( '#mwe-upwiz-upload-ctrl' ).removeAttr( 'disabled' ); |
| 2031 | + } else { |
| 2032 | + $j( '#mwe-upwiz-upload-ctrl' ).attr( 'disabled', 'disabled' ); |
| 2033 | + } |
| 2034 | + |
1960 | 2035 | if ( _this.uploads.length < _this.maxUploads ) { |
1961 | 2036 | $j( '#mwe-upwiz-add-file' ).removeAttr( 'disabled' ); |
1962 | 2037 | } else { |
— | — | @@ -1963,21 +2038,7 @@ |
1964 | 2039 | } |
1965 | 2040 | |
1966 | 2041 | |
1967 | | - // Can we enable the "start uploads" button? |
1968 | | - var hasFile; |
1969 | | - $j.each( _this.uploads, function (i, upload) { |
1970 | | - if ( upload.originalFilename ) { |
1971 | | - hasFile = true; |
1972 | | - return false; // break $j.each |
1973 | | - } |
1974 | | - } ); |
1975 | 2042 | |
1976 | | - if ( hasFile ) { |
1977 | | - $j( '#mwe-upwiz-upload-ctrl' ).removeAttr( 'disabled' ); |
1978 | | - } else { |
1979 | | - $j( '#mwe-upwiz-upload-ctrl' ).attr( 'disabled', 'disabled' ); |
1980 | | - } |
1981 | | - |
1982 | 2043 | }, |
1983 | 2044 | |
1984 | 2045 | /** |
Index: branches/js2-work/phase3/js/mwEmbed/modules/UploadWizard/css/uploadWizard.css |
— | — | @@ -5,6 +5,9 @@ |
6 | 6 | display: inline; |
7 | 7 | } |
8 | 8 | |
| 9 | +#upload-wizard { |
| 10 | + margin-top: 18px; |
| 11 | +} |
9 | 12 | |
10 | 13 | /* |
11 | 14 | .upload-section { |
— | — | @@ -82,6 +85,17 @@ |
83 | 86 | padding: 1em; |
84 | 87 | } |
85 | 88 | |
| 89 | +#mwe-upwiz-add-file { |
| 90 | + margin: 8px; |
| 91 | + padding: 16px; |
| 92 | + font-size: 16px; |
| 93 | +} |
| 94 | + |
| 95 | +/* NOT a pseudoclass */ |
| 96 | +#mwe-upwiz-add-file.hover { |
| 97 | + text-decoration: underline; |
| 98 | +} |
| 99 | + |
86 | 100 | /* perhaps a general class for links that are actually "buttons" */ |
87 | 101 | #mwe-upwiz-add-file, .mwe-upwiz-remove, .mwe-upwiz-more-options { |
88 | 102 | cursor: pointer; |
— | — | @@ -89,25 +103,40 @@ |
90 | 104 | |
91 | 105 | /* CSS styling hack for file inputs - http://www.quirksmode.org/dom/inputfile.html */ |
92 | 106 | .mwe-upwiz-file-ctrl-container { |
93 | | - position: relative; |
94 | | - display: inline; |
| 107 | + position: absolute; |
| 108 | + overflow: hidden; |
95 | 109 | } |
96 | 110 | |
97 | | -.mwe-upwiz-file, .mwe-upwiz-visible-file { |
98 | | - width: 250px; |
99 | | - height: 20px; |
| 111 | +.mwe-upwiz-file-input, .mwe-upwiz-visible-file { |
100 | 112 | cursor: pointer; |
101 | 113 | } |
102 | 114 | |
| 115 | +/* file inputs are freakishly large to overflow the containing div -- we get a div |
| 116 | + that can act as a more styleable single-click file input */ |
| 117 | +.mwe-upwiz-file-input { |
| 118 | + font-size: 100px; |
| 119 | + -moz-opacity: 0.3; |
| 120 | + filter:alpha(opacity: 0); |
| 121 | + opacity: 0; |
| 122 | + z-index: 2; |
| 123 | +} |
| 124 | + |
| 125 | +} |
| 126 | + |
| 127 | +.mwe-upwiz-file { |
| 128 | + height: 24px; |
| 129 | +} |
| 130 | + |
103 | 131 | .mwe-upwiz-visible-file { |
104 | | - position: absolute; |
105 | | - top: 0px; |
106 | | - left: 0px; |
107 | | - z-index: 1; |
| 132 | + width: 300px; |
| 133 | + height: 18px; |
| 134 | + float: left; |
| 135 | + /* top: 0px; */ |
| 136 | + /* left: 0px; */ |
108 | 137 | white-space: nowrap; |
109 | 138 | overflow: hidden; |
110 | 139 | |
111 | | - border: 1px solid blue; /* XXX just to make it visible for now */ |
| 140 | + /* border: 1px solid blue; XXX just to make it visible for now */ |
112 | 141 | } |
113 | 142 | |
114 | 143 | /* XXX we probably have a standard for this */ |
— | — | @@ -118,26 +147,17 @@ |
119 | 148 | } |
120 | 149 | |
121 | 150 | |
122 | | -.mwe-upwiz-file { |
123 | | - position: relative; |
124 | | - -moz-opacity: 0; |
125 | | - filter:alpha(opacity: 0); |
126 | | - opacity: 0; |
127 | | - z-index: 2; |
128 | | -} |
129 | | - |
| 151 | +/* |
130 | 152 | #mwe-upwiz-select-files { |
131 | 153 | float: left; |
132 | 154 | width: 100px; |
133 | 155 | } |
| 156 | +*/ |
134 | 157 | |
135 | 158 | #mwe-upwiz-files { |
136 | | - margin-left: 100px; |
| 159 | + /* margin-left: 100px; */ |
137 | 160 | } |
138 | 161 | |
139 | | -#mwe-upwiz-add-file { |
140 | | - margin-left: 100px; |
141 | | -} |
142 | 162 | |
143 | 163 | .mwe-upwiz-remove { |
144 | 164 | margin-left: 5px; |