r81228 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r81227‎ | r81228 | r81229 >
Date:03:46, 31 January 2011
Author:brion
Status:deferred
Tags:
Comment:
SVGEdit extension UI prettification, fixes.

Merge from git workspace:

924efe2 add svg-edit subdir to .gitignore; using svn externals now on the svn side, don't need it in the git work space
fa2488b resizable :D
5252e48 Initialize canvas dimensions to match the file we're going to stuff in
f1832dd fix for reload after save when opening new window with edit drawing tab
6dd4ac8 Cleanup for the spinner -> reload behavior on single-file view/edits
35d6b83 Cleanup on spinner & post-save reload
53ab4af Break out SVG Editor editing bits from the file-page button triggers. Workaround for bug 27054
4100de4 fix up initial sizing & scrolling: make sure the svg-edit area is within viewport when launched.
f84f39d Start prettying things up: put the editor inline by default, and size it to more or less fit the file vertically. Need to get the spinner back, and a
71cfbc4 Moved ajax-loader.gif into modules/images to work around bug 27052
0d8c2ab Add cactions tab for SVG editor; unfortunately on Vector this gets hidden in the overflow menu. Keeping the button as well for now.
Modified paths:
  • /trunk/extensions/SVGEdit/.gitignore (modified) (history)
  • /trunk/extensions/SVGEdit/SVGEdit.php (modified) (history)
  • /trunk/extensions/SVGEdit/modules/ext.svgedit.editButton.css (modified) (history)
  • /trunk/extensions/SVGEdit/modules/ext.svgedit.editButton.js (modified) (history)
  • /trunk/extensions/SVGEdit/modules/ext.svgedit.editor.js (added) (history)
  • /trunk/extensions/SVGEdit/modules/ext.svgedit.io.js (modified) (history)
  • /trunk/extensions/SVGEdit/modules/images/toolbar-base.png (added) (history)

Diff [purge]

Index: trunk/extensions/SVGEdit/.gitignore
@@ -1,3 +1,4 @@
22 *~
33 .svn
4 -.DS_Store
\ No newline at end of file
 4+.DS_Store
 5+svg-edit
Index: trunk/extensions/SVGEdit/modules/ext.svgedit.editButton.js
@@ -3,6 +3,8 @@
44 * @copyright 2010 Brion Vibber <brion@pobox.com>
55 */
66
 7+(function($, mw) {
 8+
79 $(document).ready(function() {
810 // We probably should check http://www.w3.org/TR/SVG11/feature#SVG-dynamic
911 // but Firefox is missing a couple random subfeatures.
@@ -17,97 +19,46 @@
1820 && wgAction == 'view'
1921 && wgTitle.match(/\.svg$/i)) {
2022
21 - var triggerSVGEdit = function(filename) {
22 - var svgedit;
23 - var pipe;
24 - var url = wgSVGEditEditor ||
25 - (wgScriptPath + '/extensions/SVGEdit/svg-edit/svg-editor.html');
26 -
27 - $('body')
28 - .append('<div id="mw-svgedit">' +
29 - '<div id="mw-svgedit-toolbar">' +
30 - '<label id="mw-svgedit-summary-label"></label> ' +
31 - '<input id="mw-svgedit-summary" size="60" /> ' +
32 - '<button id="mw-svgedit-save"></button> ' +
33 - '<button id="mw-svgedit-close"></button>' +
34 - '</div>' +
35 - '<iframe id="mw-svgedit-frame" width="100%" height="90%"></iframe>' +
36 - '<div id="mw-svgedit-spinner"></div>' +
37 - '</div>');
38 -
39 - $('#mw-svgedit-summary-label')
40 - .text(mediaWiki.msg('svgedit-summary-label'));
41 -
42 - $('#mw-svgedit-summary')
43 - .val(mediaWiki.msg('svgedit-summary-default') + ' ');
44 -
45 - $('#mw-svgedit-save')
46 - .text(mediaWiki.msg('svgedit-editor-save-close'))
47 - .click(function() {
48 - $('#mw-svgedit-spinner').show();
49 - svgedit.getSvgString()(function(svg) {
50 - var comment = $('#mw-svgedit-summary').val();
51 - mwSVG.saveSVG(filename, svg, comment, function(data, textStatus, xhr) {
52 - if (data.upload && data.upload.result == "Success") {
53 - // kill the editor so it doesn't prompt us to save
54 - $('#mw-svgedit-frame').remove();
55 - // refresh parent window
56 - window.location = window.location;
57 - } else if (data.error && data.error.info) {
58 - $('#mw-svgedit-spinner').hide();
59 - alert('Error saving file: ' + data.error.info);
60 - } else {
61 - $('#mw-svgedit-spinner').hide();
62 - alert('Possible error saving file...');
63 - }
64 - });
65 - });
66 - });
67 -
68 - $('#mw-svgedit-close')
69 - .text(mediaWiki.msg('svgedit-editor-close'))
70 - .click(function() {
71 - $('#mw-svgedit').remove();
72 - });
73 -
74 - $('#mw-svgedit-frame')
75 - .load(function() {
76 - svgedit = new embedded_svg_edit(this);
77 -
78 - // Load up the original file!
79 - mwSVG.fetchSVG(filename, function(xmlSource, textStatus, xhr) {
80 - svgedit.setSvgString(xmlSource)(function() {
81 - $('#mw-svgedit-spinner').hide();
82 - });
83 - });
84 - })
85 - .attr('src', url);
 23+ var trigger = function() {
 24+ mw.svgedit.open({
 25+ filename: wgTitle,
 26+ replace: '#file',
 27+ onclose: function(filename) {
 28+ if (filename) {
 29+ // Saved! Refresh parent window...
 30+ window.location.reload(true);
 31+ }
 32+ },
 33+ leaveopen: true // Our reload will get rid of the UI.
 34+ })
8635 };
8736
88 - var tab = mediaWiki.util.addPortletLink('p-cactions',
 37+ var tab = mw.util.addPortletLink('p-cactions',
8938 document.location + '#!action=svgedit',
90 - mediaWiki.msg('svgedit-edit-tab'),
 39+ mw.msg('svgedit-edit-tab'),
9140 'ca-ext-svgedit',
92 - mediaWiki.msg('svgedit-edit-tab-tooltip'),
 41+ mw.msg('svgedit-edit-tab-tooltip'),
9342 '',
9443 document.getElementById('ca-edit'));
9544
9645 $(tab).find('a').click(function(event) {
97 - triggerSVGEdit(wgTitle);
 46+ trigger();
9847 event.preventDefault();
9948 return false;
10049 });
10150
10251 var button = $('<button></button>')
103 - .text(mediaWiki.msg('svgedit-editbutton-edit'))
 52+ .text(mw.msg('svgedit-editbutton-edit'))
10453 .click(function() {
105 - triggerSVGEdit(wgTitle);
 54+ trigger();
10655 });
107 -
10856 $('.fullMedia').append(button);
10957
110 - if (document.location.hash.indexOf('!action=svgedit') != -1) {
111 - triggerSVGEdit(wgTitle);
 58+ if (window.location.hash.indexOf('!action=svgedit') != -1) {
 59+ window.location.hash = '';
 60+ trigger();
11261 }
11362 }
11463 });
 64+
 65+})(jQuery, mediaWiki);
Index: trunk/extensions/SVGEdit/modules/ext.svgedit.editor.js
@@ -0,0 +1,185 @@
 2+/**
 3+ * SVGEdit extension: edit widget fun
 4+ * @copyright 2010-2011 Brion Vibber <brion@pobox.com>
 5+ */
 6+
 7+(function($, mw) {
 8+
 9+mw.svgedit = {
 10+ isOpen: false,
 11+
 12+ init: function() {
 13+
 14+ },
 15+
 16+ /**
 17+ * Open the SVG editor.
 18+ * Will have no effect if the editor is already open.
 19+ *
 20+ * @param filename: String
 21+ * @param options: object
 22+ * filename: wiki name of existing file to initially load
 23+ * replace: selector or DOM node to replace the editor with while it runs
 24+ * onclose: function(filename) callback; if saved, new file's on-wiki name is passed otherwise null
 25+ * leaveopen: pass true to leave the editor goodies up after successful save: it's caller's responsibility to tidy up the page UI state
 26+ */
 27+ open: function(options) {
 28+ if (mw.svgedit.isOpen) {
 29+ return false;
 30+ }
 31+ mw.svgedit.isOpen = true;
 32+
 33+ var url = wgSVGEditEditor ||
 34+ (wgScriptPath + '/extensions/SVGEdit/svg-edit/svg-editor.html');
 35+
 36+ var filename = options.filename || null;
 37+ var replace = options.replace || null;
 38+ var onclose = options.onclose || null;
 39+ var leaveopen = options.leaveopen || false;
 40+
 41+ var svgedit = null; // to be filled out when iframe is loaded
 42+ var saved = false;
 43+
 44+ // @fixme not a stable interface; use API instead?
 45+ var origWidth = parseInt($('#mw_metadata tr.svg-width td').text());
 46+ var origHeight = parseInt($('#mw_metadata tr.svg-height td').text());
 47+ if (origWidth && origHeight) {
 48+ // Initialize the canvas dimensions to the image's defined size...
 49+ url += '?dimensions=' + origWidth + ',' + origHeight;
 50+ }
 51+
 52+ var minHeight = 480;
 53+ var preferredHeight = origHeight + 180; // leave space for toolbars and UI inside the iframe
 54+ var windowHeight = $(window).height() - 40; // leave space for our toolbar outside the iframe
 55+ var minHeight = Math.min(windowHeight, preferredHeight);
 56+ var initHeight = Math.max(minHeight, minHeight);
 57+
 58+ // @fixme
 59+ var orig = $(replace);
 60+
 61+ orig.hide();
 62+ orig.before('<div id="mw-svgedit">' +
 63+ '<div id="mw-svgedit-toolbar">' +
 64+ '<label id="mw-svgedit-summary-label"></label> ' +
 65+ '<input id="mw-svgedit-summary" size="60" /> ' +
 66+ '<button id="mw-svgedit-save"></button> ' +
 67+ '<button id="mw-svgedit-close"></button>' +
 68+ '</div>' +
 69+ '<div id="mw-svgedit-frame-holder" style="width: 100%; height: ' + initHeight + 'px">' +
 70+ '<iframe id="mw-svgedit-frame" width="100%" height="100%"></iframe>' +
 71+ '</div>' +
 72+ '</div>');
 73+
 74+ var frame = $('#mw-svgedit-frame');
 75+ $('#mw-svgedit-frame-holder').resizable({
 76+ handles: 's',
 77+ helper: 'mw-svgedit-resize',
 78+ minHeight: minHeight
 79+ });
 80+
 81+ $('body').append('<div id="mw-svgedit-spinner"></div>');
 82+ var spinner = $('#mw-svgedit-spinner');
 83+
 84+ /**
 85+ * Close the editor when we're ready.
 86+ * Alert the caller's callback if provided.
 87+ */
 88+ var closeEditor = function() {
 89+ // Always remove the frame; not sure how to shut it up
 90+ // with its beforeunload handler.
 91+ $('#mw-svgedit-frame').replaceWith('<div style="height: ' + initHeight + 'px"></div>');
 92+ if (!(saved && leaveopen)) {
 93+ // Clean up editor UI unless we've been asked to leave
 94+ // things open for caller after successful save.
 95+ $('#mw-svgedit').remove();
 96+ spinner.remove();
 97+ orig.show();
 98+ mw.svgedit.isOpen = false;
 99+ }
 100+ if (onclose) {
 101+ onclose(saved ? filename : null);
 102+ }
 103+ };
 104+
 105+ var spinnerOn = function() {
 106+ $('#mw-svgedit-summary').attr('disabled', 'disabled');
 107+ $('#mw-svgedit-save').attr('disabled', 'disabled');
 108+ var offset = frame.offset();
 109+ spinner
 110+ .css('left', offset.left)
 111+ .css('top', offset.top)
 112+ .width(frame.width())
 113+ .height(frame.height())
 114+ .show();
 115+ };
 116+ var spinnerOff = function() {
 117+ $('#mw-svgedit-summary').attr('disabled', null);
 118+ $('#mw-svgedit-save').attr('disabled', null);
 119+ spinner.hide();
 120+ };
 121+
 122+ $('#mw-svgedit-summary-label')
 123+ .text(mediaWiki.msg('svgedit-summary-label'));
 124+
 125+ $('#mw-svgedit-summary')
 126+ .val(mediaWiki.msg('svgedit-summary-default') + ' ');
 127+
 128+ $('#mw-svgedit-save')
 129+ .text(mediaWiki.msg('svgedit-editor-save-close'))
 130+ .click(function() {
 131+ spinnerOn();
 132+ svgedit.getSvgString()(function(svg) {
 133+ var comment = $('#mw-svgedit-summary').val();
 134+ mwSVG.saveSVG(filename, svg, comment, function(data, textStatus, xhr) {
 135+ if (data.upload && data.upload.result == "Success") {
 136+ saved = true;
 137+ closeEditor();
 138+ } else if (data.error && data.error.info) {
 139+ spinnerOff();
 140+ alert('Error saving file: ' + data.error.info);
 141+ } else {
 142+ spinnerOff();
 143+ alert('Possible error saving file...');
 144+ }
 145+ });
 146+ });
 147+ });
 148+
 149+ $('#mw-svgedit-close')
 150+ .text(mediaWiki.msg('svgedit-editor-close'))
 151+ .click(function() {
 152+ closeEditor();
 153+ });
 154+
 155+ // Ok, let's load up the goodies!
 156+ spinnerOn();
 157+ $('#mw-svgedit-frame')
 158+ .load(function() {
 159+ svgedit = new embedded_svg_edit(this);
 160+
 161+ // Load up the original file!
 162+ if (filename) {
 163+ mwSVG.fetchSVG(filename, function(xmlSource, textStatus, xhr) {
 164+ svgedit.setSvgString(xmlSource)(function() {
 165+ spinnerOff();
 166+ });
 167+ });
 168+ } else {
 169+ spinnerOff();
 170+ }
 171+ })
 172+ .attr('src', url);
 173+
 174+ // Check if the editor is fully in view; if not, scroll to the top.
 175+ var win = $(window);
 176+ var scrollTop = win.scrollTop();
 177+ var scrollBottom = scrollTop + windowHeight;
 178+ var top = $('#mw-svgedit').offset().top;
 179+ var bottom = top + $('#mw-svgedit').height();
 180+ if (top < scrollTop || bottom > scrollBottom) {
 181+ win.scrollTop(top);
 182+ }
 183+ }
 184+};
 185+
 186+})(jQuery, mediaWiki);
Index: trunk/extensions/SVGEdit/modules/ext.svgedit.io.js
@@ -97,4 +97,4 @@
9898 $.ajax(ajaxSettings);
9999 });
100100 }
101 -}
 101+};
Index: trunk/extensions/SVGEdit/modules/images/toolbar-base.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: trunk/extensions/SVGEdit/modules/images/toolbar-base.png
___________________________________________________________________
Added: svn:mime-type
102102 + application/octet-stream
Index: trunk/extensions/SVGEdit/modules/ext.svgedit.editButton.css
@@ -1,41 +1,42 @@
22 #mw-svgedit {
3 - background: rgba(0, 0, 0, 0.5);
4 - position: fixed;
5 - left: 0;
6 - top: 0;
7 - right: 0;
8 - bottom: 0;
9 - z-index: 99999;
 3+ border: solid 1px silver;
 4+ background: white
 5+ url("images/toolbar-base.png")
 6+ repeat-x;
 7+ margin-bottom: 16px;
108 }
119 #mw-svgedit-toolbar {
12 - padding: 6px;
13 - background: #f4f4f4;
 10+ padding: 4px 12px;
1411 }
15 -#mw-svgedit-buttons {
16 - position: absolute;
17 - top: 4px;
18 - right: 4px;
19 - text-align: right;
20 -}
2112
2213 #mw-svgedit-frame {
23 - position: absolute;
2414 border: none;
25 - top: 2em;
26 - left: 0;
27 - right: 0;
28 - bottom: 0;
 15+ overflow: hidden;
2916 }
3017
3118 #mw-svgedit-spinner {
3219 position: absolute;
33 - top: 2em;
34 - left: 0;
35 - right: 0;
36 - bottom: 0;
 20+ top: 0;
 21+ left: 0;
 22+ width: 0;
 23+ height: 0;
3724 background: rgba(0,0,0,0.5)
3825 url("images/ajax-loader.gif")
3926 50%
4027 no-repeat;
4128 z-index: 999999
4229 }
 30+
 31+#mw-svgedit .ui-resizable-handle {
 32+ background: #aaa;
 33+ border: solid 1px #888;
 34+ border-top: solid 1px #ccc;
 35+ border-left: solid 1px #ccc;
 36+}
 37+#mw-svgedit .ui-resizable-handle:hover {
 38+ background: #eee;
 39+}
 40+.mw-svgedit-resize {
 41+ background: rgba(0,0,0,0.5);
 42+ border-bottom: solid 2px blue;
 43+}
Index: trunk/extensions/SVGEdit/SVGEdit.php
@@ -36,6 +36,7 @@
3737 'ext.svgedit.embedapi.js',
3838 'ext.svgedit.formmultipart.js',
3939 'ext.svgedit.io.js',
 40+ 'ext.svgedit.editor.js',
4041 'ext.svgedit.editButton.js',
4142 ),
4243 'styles' => array(
@@ -50,6 +51,9 @@
5152 'svgedit-edit-tab',
5253 'svgedit-edit-tab-tooltip'
5354 ),
 55+ 'dependencies' => array(
 56+ 'jquery.ui.resizable'
 57+ )
5458 ),
5559 );
5660

Follow-up revisions

RevisionCommit summaryAuthorDate
r83897(bug 27054) Implicit end of statement can break stuff when files are combined...catrope14:25, 14 March 2011
r83902(bug 27052) CSSMin generated URLs like foo//../bar in some cases, which appar...catrope15:01, 14 March 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r81223SVGEdit extension: work around bug 27052 by moving ajax-loader.gif under modu...brion22:36, 30 January 2011

Status & tagging log