preload theme wizard with existing properties (#9644)
This commit is contained in:
Родитель
1cbaf538b0
Коммит
6c8ab97032
|
@ -9,6 +9,18 @@
|
|||
{% block primary %}
|
||||
<h3>{{ _('Theme generator') }}</h3>
|
||||
<div id="theme-wizard" data-version="{{ version_number }}">
|
||||
{% if unsupported_properties %}
|
||||
<div class="notification-box error">
|
||||
{{ _('Warning: the following manifest properties that your most recent version '
|
||||
"upload used in it's manifest are unsupported in this wizard and will be ignored:") }}
|
||||
<ul class="note">
|
||||
{% for prop in unsupported_properties %}
|
||||
<li>{{ prop }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
<h3>{{ _('Theme name') }}<span class="req" title="{{ _('required') }}">*</span></h3>
|
||||
{% if addon %}
|
||||
|
@ -19,7 +31,7 @@
|
|||
<input type="text" id="theme-name"/>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div id="theme-header" class="row">
|
||||
<div id="theme-header" class="row" data-existing-header="{{ existing_properties.get('images', {}).get('headerURL','') }}">
|
||||
<label class="row" for="header-img">
|
||||
<h3>{{ _('Select a header image for your theme') }}<span class="req" title="{{ _('required') }}">*</span></h3>
|
||||
</label>
|
||||
|
@ -38,18 +50,11 @@
|
|||
</div>
|
||||
<div class="colors">
|
||||
<h3>{{ _('Select colors for your theme') }}</h3>
|
||||
{% set colors = [
|
||||
('accentcolor', _('Header area background'), _('The color of the header area background, displayed in the part of the header not covered or visible through the header image. Manifest field: accentcolor.'), 'rgba(229,230,232,1)'),
|
||||
('textcolor', _('Header area text and icons'), _('The color of the text and icons in the header area, except the active tab. Manifest field: textcolor.'), 'rgba(0,0,0,1'),
|
||||
('toolbar', _('Toolbar area background'), _('The background color for the navigation bar, the bookmarks bar, and the selected tab. Manifest field: toolbar.'), false),
|
||||
('toolbar_text', _('Toolbar area text and icons'), _('The color of the text and icons in the toolbar and the active tab. Manifest field: toolbar_text.'), false),
|
||||
('toolbar_field', _('Toolbar field area background'), _('The background color for fields in the toolbar, such as the URL bar. Manifest field: toolbar_field.'), false),
|
||||
('toolbar_field_text', _('Toolbar field area text'), _('The color of text in fields in the toolbar, such as the URL bar. Manifest field: toolbar_field_text.'), false)] %}
|
||||
|
||||
<ul class="colors">
|
||||
{% set property_list = ['textcolor','toolbar_text', 'toolbar_field_text'] %}
|
||||
{% set property_list_left = ['textcolor','toolbar_text', 'toolbar_field_text'] %}
|
||||
{% set existing_colors = existing_properties['colors'] or {} %}
|
||||
{% for (property, label, tip, val_default) in colors %}
|
||||
{% if property in property_list %}
|
||||
{% if property in property_list_left %}
|
||||
<li class="row left">
|
||||
{% else %}
|
||||
<li class="row">
|
||||
|
@ -65,8 +70,10 @@
|
|||
<span class="tip tooltip" title="{{ tip }}" data-oldtitle="">?</span>
|
||||
</span>
|
||||
</label>
|
||||
<input class="color-picker" id="{{ property }}" name="{{ property }}"
|
||||
type="text"{{ ('value=' + val_default + '') if val_default else '' }}>
|
||||
{% with value = existing_colors.get(property, val_default) %}
|
||||
<input class="color-picker" id="{{ property }}" name="{{ property }}"
|
||||
type="text"{{ (' value=' + value) if value else '' }}>
|
||||
{% endwith %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
|
|
@ -5,12 +5,14 @@ from django.conf import settings
|
|||
from django.test.utils import override_settings
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
from waffle.testutils import override_switch
|
||||
|
||||
from celery.result import AsyncResult
|
||||
from six import text_type
|
||||
|
||||
from olympia import amo
|
||||
from olympia.amo.storage_utils import copy_stored_file
|
||||
from olympia.amo.tests import (
|
||||
addon_factory, TestCase, user_factory, version_factory)
|
||||
from olympia.devhub import tasks, utils
|
||||
|
@ -414,3 +416,49 @@ class TestGetAddonAkismetReports(TestCase):
|
|||
property_name='description', property_value=u'lé foo',
|
||||
user_agent=user_agent, referrer=referrer)]
|
||||
self.create_for_addon_mock.assert_has_calls(calls, any_order=True)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_extract_theme_properties():
|
||||
addon = addon_factory(type=amo.ADDON_STATICTHEME)
|
||||
result = utils.extract_theme_properties(
|
||||
addon, addon.current_version.channel)
|
||||
assert result == {} # There's no file, but it be should safely handled.
|
||||
|
||||
# Add the zip in the right place
|
||||
zip_file = os.path.join(
|
||||
settings.ROOT, 'src/olympia/devhub/tests/addons/static_theme.zip')
|
||||
copy_stored_file(zip_file, addon.current_version.all_files[0].file_path)
|
||||
result = utils.extract_theme_properties(
|
||||
addon, addon.current_version.channel)
|
||||
assert result['colors'] == {
|
||||
"accentcolor": "#adb09f",
|
||||
"textcolor": "#000"
|
||||
}
|
||||
assert result['images'] == {
|
||||
"headerURL": '%s%s//%s/%s/%s' % (
|
||||
settings.MEDIA_URL, 'addons', text_type(addon.id),
|
||||
text_type(addon.current_version.id), 'weta.png')
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_wizard_unsupported_properties():
|
||||
data = {
|
||||
'colors': {
|
||||
'foo': '#111111',
|
||||
'baa': '#222222',
|
||||
'extracolor': 'rgb(1,2,3,0)',
|
||||
},
|
||||
'images': {
|
||||
'headerURL': 'png.png',
|
||||
'additionalBackground': 'somethingelse.png',
|
||||
},
|
||||
'extrathing': {
|
||||
'doesnt': 'matter',
|
||||
},
|
||||
}
|
||||
fields = ['foo', 'baa']
|
||||
properties = utils.wizard_unsupported_properties(
|
||||
data, fields)
|
||||
assert properties == ['extrathing', 'extracolor', 'additionalBackground']
|
||||
|
|
|
@ -1590,10 +1590,21 @@ class VersionSubmitUploadMixin(object):
|
|||
channel = ('listed' if self.channel == amo.RELEASE_CHANNEL_LISTED else
|
||||
'unlisted')
|
||||
self.addon.update(type=amo.ADDON_STATICTHEME)
|
||||
# Check we get the correct template.
|
||||
# Get the correct template.
|
||||
self.url = reverse('devhub.submit.version.wizard',
|
||||
args=[self.addon.slug, channel])
|
||||
response = self.client.get(self.url)
|
||||
mock_point = 'olympia.devhub.views.extract_theme_properties'
|
||||
with mock.patch(mock_point) as extract_theme_properties_mock:
|
||||
extract_theme_properties_mock.return_value = {
|
||||
'colors': {
|
||||
'accentcolor': '#123456',
|
||||
'textcolor': 'rgba(1,2,3,0.4)',
|
||||
},
|
||||
'images': {
|
||||
'headerURL': 'header.png',
|
||||
}
|
||||
}
|
||||
response = self.client.get(self.url)
|
||||
assert response.status_code == 200
|
||||
doc = pq(response.content)
|
||||
assert doc('#theme-wizard')
|
||||
|
@ -1601,6 +1612,77 @@ class VersionSubmitUploadMixin(object):
|
|||
assert doc('input#theme-name').attr('type') == 'hidden'
|
||||
assert doc('input#theme-name').attr('value') == (
|
||||
unicode(self.addon.name))
|
||||
# Existing colors should be the default values for the fields
|
||||
assert doc('#accentcolor').attr('value') == '#123456'
|
||||
assert doc('#textcolor').attr('value') == 'rgba(1,2,3,0.4)'
|
||||
# And the theme header url is there for the JS to load
|
||||
assert doc('#theme-header').attr('data-existing-header') == (
|
||||
'header.png')
|
||||
# No warning about extra properties
|
||||
assert 'are unsupported in this wizard' not in response.content
|
||||
|
||||
# And then check the upload works.
|
||||
path = os.path.join(
|
||||
settings.ROOT, 'src/olympia/devhub/tests/addons/static_theme.zip')
|
||||
self.upload = self.get_upload(abspath=path)
|
||||
response = self.post()
|
||||
|
||||
version = self.addon.find_latest_version(channel=self.channel)
|
||||
assert version.channel == self.channel
|
||||
assert version.all_files[0].status == (
|
||||
amo.STATUS_AWAITING_REVIEW
|
||||
if self.channel == amo.RELEASE_CHANNEL_LISTED else
|
||||
amo.STATUS_PUBLIC)
|
||||
self.assert3xx(response, self.get_next_url(version))
|
||||
log_items = ActivityLog.objects.for_addons(self.addon)
|
||||
assert log_items.filter(action=amo.LOG.ADD_VERSION.id)
|
||||
if self.channel == amo.RELEASE_CHANNEL_LISTED:
|
||||
previews = list(version.previews.all())
|
||||
assert len(previews) == 3
|
||||
assert storage.exists(previews[0].image_path)
|
||||
assert storage.exists(previews[1].image_path)
|
||||
assert storage.exists(previews[1].image_path)
|
||||
else:
|
||||
assert version.previews.all().count() == 0
|
||||
|
||||
def test_static_theme_wizard_unsupported_properties(self):
|
||||
channel = ('listed' if self.channel == amo.RELEASE_CHANNEL_LISTED else
|
||||
'unlisted')
|
||||
self.addon.update(type=amo.ADDON_STATICTHEME)
|
||||
# Get the correct template.
|
||||
self.url = reverse('devhub.submit.version.wizard',
|
||||
args=[self.addon.slug, channel])
|
||||
mock_point = 'olympia.devhub.views.extract_theme_properties'
|
||||
with mock.patch(mock_point) as extract_theme_properties_mock:
|
||||
extract_theme_properties_mock.return_value = {
|
||||
'colors': {
|
||||
'accentcolor': '#123456',
|
||||
'textcolor': 'rgba(1,2,3,0.4)',
|
||||
'tab_line': '#123',
|
||||
},
|
||||
'images': {
|
||||
'additional_backgrounds': [],
|
||||
},
|
||||
'something_extra': {},
|
||||
}
|
||||
response = self.client.get(self.url)
|
||||
assert response.status_code == 200
|
||||
doc = pq(response.content)
|
||||
assert doc('#theme-wizard')
|
||||
assert doc('#theme-wizard').attr('data-version') == '3.0'
|
||||
assert doc('input#theme-name').attr('type') == 'hidden'
|
||||
assert doc('input#theme-name').attr('value') == (
|
||||
unicode(self.addon.name))
|
||||
# Existing colors should be the default values for the fields
|
||||
assert doc('#accentcolor').attr('value') == '#123456'
|
||||
assert doc('#textcolor').attr('value') == 'rgba(1,2,3,0.4)'
|
||||
# Warning about extra properties this time:
|
||||
assert 'are unsupported in this wizard' in response.content
|
||||
unsupported_list = doc('.notification-box.error ul.note li')
|
||||
assert unsupported_list.length == 3
|
||||
assert 'tab_line' in unsupported_list.text()
|
||||
assert 'additional_backgrounds' in unsupported_list.text()
|
||||
assert 'something_extra' in unsupported_list.text()
|
||||
|
||||
# And then check the upload works.
|
||||
path = os.path.join(
|
||||
|
|
|
@ -11,15 +11,17 @@ from six import text_type
|
|||
|
||||
import olympia.core.logger
|
||||
|
||||
from olympia import amo
|
||||
from olympia import amo, core
|
||||
from olympia.addons.models import Addon
|
||||
from olympia.amo.templatetags.jinja_helpers import user_media_url
|
||||
from olympia.amo.urlresolvers import linkify_escape
|
||||
from olympia.files.models import File, FileUpload
|
||||
from olympia.files.utils import parse_addon
|
||||
from olympia.files.utils import parse_addon, parse_xpi
|
||||
from olympia.lib.akismet.models import AkismetReport
|
||||
from olympia.tags.models import Tag
|
||||
from olympia.translations.models import Translation
|
||||
from olympia.versions.compare import version_int
|
||||
from olympia.versions.utils import process_color_value
|
||||
|
||||
from . import tasks
|
||||
|
||||
|
@ -357,3 +359,45 @@ def get_addon_akismet_reports(user, user_agent, referrer, upload=None,
|
|||
referrer=referrer)
|
||||
reports.append((prop, report))
|
||||
return reports
|
||||
|
||||
|
||||
def extract_theme_properties(addon, channel):
|
||||
version = addon.find_latest_version(channel)
|
||||
if not version or not version.all_files:
|
||||
return {}
|
||||
try:
|
||||
parsed_data = parse_xpi(
|
||||
version.all_files[0].file_path, addon=addon, user=core.get_user())
|
||||
except ValidationError:
|
||||
# If we can't parse the existing manifest safely return.
|
||||
return {}
|
||||
theme_props = parsed_data.get('theme', {})
|
||||
# pre-process colors to convert chrome style colors and strip spaces
|
||||
theme_props['colors'] = dict(
|
||||
process_color_value(prop, color)
|
||||
for prop, color in theme_props.get('colors', {}).items())
|
||||
# replace headerURL with path to existing background
|
||||
if 'images' in theme_props:
|
||||
if 'theme_frame' in theme_props['images']:
|
||||
header_url = theme_props['images'].pop('theme_frame')
|
||||
if 'headerURL' in theme_props['images']:
|
||||
header_url = theme_props['images'].pop('headerURL')
|
||||
if header_url:
|
||||
theme_props['images']['headerURL'] = '/'.join((
|
||||
user_media_url('addons'), text_type(addon.id),
|
||||
text_type(version.id), header_url))
|
||||
return theme_props
|
||||
|
||||
|
||||
def wizard_unsupported_properties(data, wizard_fields):
|
||||
# collect any 'theme' level unsupported properties
|
||||
unsupported = [
|
||||
key for key in data.keys() if key not in ['colors', 'images']]
|
||||
# and any unsupported 'colors' properties
|
||||
unsupported += [
|
||||
key for key in data.get('colors', {}) if key not in wizard_fields]
|
||||
# and finally any 'images' properties (wizard only supports the background)
|
||||
unsupported += [
|
||||
key for key in data.get('images', {}) if key != 'headerURL']
|
||||
|
||||
return unsupported
|
||||
|
|
|
@ -45,8 +45,10 @@ from olympia.devhub.forms import (
|
|||
AgreementForm, CheckCompatibilityForm, SourceForm)
|
||||
from olympia.devhub.models import BlogPost, RssKey
|
||||
from olympia.devhub.utils import (
|
||||
add_dynamic_theme_tag, fetch_existing_translations_from_addon,
|
||||
get_addon_akismet_reports, process_validation)
|
||||
add_dynamic_theme_tag, extract_theme_properties,
|
||||
fetch_existing_translations_from_addon,
|
||||
get_addon_akismet_reports, process_validation,
|
||||
wizard_unsupported_properties)
|
||||
from olympia.files.models import File, FileUpload, FileValidation
|
||||
from olympia.files.utils import parse_addon
|
||||
from olympia.lib.crypto.packaged import sign_file
|
||||
|
@ -1327,6 +1329,41 @@ def submit_version_distribution(request, addon_id, addon):
|
|||
return _submit_distribution(request, addon, 'devhub.submit.version.upload')
|
||||
|
||||
|
||||
WIZARD_COLOR_FIELDS = [
|
||||
('accentcolor',
|
||||
_(u'Header area background'),
|
||||
_(u'The color of the header area background, displayed in the part of '
|
||||
u'the header not covered or visible through the header image. Manifest '
|
||||
u'field: accentcolor.'),
|
||||
'rgba(229,230,232,1)'),
|
||||
('textcolor',
|
||||
_(u'Header area text and icons'),
|
||||
_(u'The color of the text and icons in the header area, except the '
|
||||
u'active tab. Manifest field: textcolor.'),
|
||||
'rgba(0,0,0,1'),
|
||||
('toolbar',
|
||||
_(u'Toolbar area background'),
|
||||
_(u'The background color for the navigation bar, the bookmarks bar, and '
|
||||
u'the selected tab. Manifest field: toolbar.'),
|
||||
False),
|
||||
('toolbar_text',
|
||||
_(u'Toolbar area text and icons'),
|
||||
_(u'The color of the text and icons in the toolbar and the active tab. '
|
||||
u'Manifest field: toolbar_text.'),
|
||||
False),
|
||||
('toolbar_field',
|
||||
_(u'Toolbar field area background'),
|
||||
_(u'The background color for fields in the toolbar, such as the URL bar. '
|
||||
u'Manifest field: toolbar_field.'),
|
||||
False),
|
||||
('toolbar_field_text',
|
||||
_(u'Toolbar field area text'),
|
||||
_(u'The color of text in fields in the toolbar, such as the URL bar. '
|
||||
u'Manifest field: toolbar_field_text.'),
|
||||
False)
|
||||
]
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def _submit_upload(request, addon, channel, next_view, wizard=False):
|
||||
""" If this is a new addon upload `addon` will be None.
|
||||
|
@ -1381,6 +1418,14 @@ def _submit_upload(request, addon, channel, next_view, wizard=False):
|
|||
submit_page = 'version' if addon else 'addon'
|
||||
template = ('devhub/addons/submit/upload.html' if not wizard else
|
||||
'devhub/addons/submit/wizard.html')
|
||||
existing_properties = (
|
||||
extract_theme_properties(addon, channel)
|
||||
if wizard and addon else {})
|
||||
unsupported_properties = (
|
||||
wizard_unsupported_properties(
|
||||
existing_properties,
|
||||
[field for field, _, _, _ in WIZARD_COLOR_FIELDS])
|
||||
if existing_properties else [])
|
||||
return render(request, template,
|
||||
{'new_addon_form': form,
|
||||
'is_admin': is_admin,
|
||||
|
@ -1390,6 +1435,9 @@ def _submit_upload(request, addon, channel, next_view, wizard=False):
|
|||
'submit_page': submit_page,
|
||||
'channel': channel,
|
||||
'channel_choice_text': channel_choice_text,
|
||||
'existing_properties': existing_properties,
|
||||
'colors': WIZARD_COLOR_FIELDS,
|
||||
'unsupported_properties': unsupported_properties,
|
||||
'version_number':
|
||||
get_next_version_number(addon) if wizard else None})
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@ from .utils import (
|
|||
def _build_static_theme_preview_context(theme_manifest, header_root):
|
||||
# First build the context shared by both the main preview and the thumb
|
||||
context = {'amo': amo}
|
||||
context.update(
|
||||
{process_color_value(prop, color)
|
||||
for prop, color in theme_manifest.get('colors', {}).items()})
|
||||
context.update(dict(
|
||||
process_color_value(prop, color)
|
||||
for prop, color in theme_manifest.get('colors', {}).items()))
|
||||
images_dict = theme_manifest.get('images', {})
|
||||
header_url = images_dict.get(
|
||||
'headerURL', images_dict.get('theme_frame', ''))
|
||||
|
|
|
@ -210,7 +210,7 @@ def test_generate_static_theme_preview_with_chrome_properties(
|
|||
}
|
||||
for (chrome_prop, firefox_prop) in chrome_colors.items():
|
||||
color_list = theme_manifest['colors'][chrome_prop]
|
||||
color = 'rgb(%s, %s, %s)' % tuple(color_list)
|
||||
color = 'rgb(%s,%s,%s)' % tuple(color_list)
|
||||
colors.append('class="%s" fill="%s"' % (firefox_prop, color))
|
||||
|
||||
header_svg = write_svg_to_png_mock.call_args_list[0][0][0]
|
||||
|
|
|
@ -127,10 +127,11 @@ def test_additional_background(
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
'chrome_prop, chrome_color, firefox_prop, css_color', (
|
||||
('bookmark_text', [2, 3, 4], 'toolbar_text', u'rgb(2, 3, 4)'),
|
||||
('frame', [12, 13, 14], 'accentcolor', u'rgb(12, 13, 14)'),
|
||||
('frame_inactive', [22, 23, 24], 'accentcolor', u'rgb(22, 23, 24)'),
|
||||
('tab_background_text', [32, 33, 34], 'textcolor', u'rgb(32, 33, 34)'),
|
||||
('bookmark_text', [2, 3, 4], 'toolbar_text', u'rgb(2,3,4)'),
|
||||
('frame', [12, 13, 14], 'accentcolor', u'rgb(12,13,14)'),
|
||||
('frame_inactive', [22, 23, 24], 'accentcolor', u'rgb(22,23,24)'),
|
||||
('tab_background_text', [32, 33, 34], 'textcolor', u'rgb(32,33,34)'),
|
||||
('accentcolor', u'rgb(32, 33, 34)', 'accentcolor', u'rgb(32,33,34)'),
|
||||
)
|
||||
)
|
||||
def test_process_color_value(chrome_prop, chrome_color, firefox_prop,
|
||||
|
|
|
@ -119,5 +119,6 @@ CHROME_COLOR_TO_CSS = {
|
|||
def process_color_value(prop, value):
|
||||
prop = CHROME_COLOR_TO_CSS.get(prop, prop)
|
||||
if isinstance(value, list) and len(value) == 3:
|
||||
return prop, u'rgb(%s, %s, %s)' % tuple(value)
|
||||
return prop, unicode(value)
|
||||
return prop, u'rgb(%s,%s,%s)' % tuple(value)
|
||||
# strip out spaces because jquery.minicolors chokes on them
|
||||
return prop, unicode(value).replace(' ', '')
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
.note {
|
||||
display: block;
|
||||
padding-top: 2px;
|
||||
margin-bottom: 0px;
|
||||
li {
|
||||
display: inline-block;
|
||||
font-size: 0.9em;
|
||||
|
@ -107,4 +108,4 @@
|
|||
.html-rtl .button.upload.uploading {
|
||||
background-position: 5% center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,13 @@ $(document).ready(function() {
|
|||
|
||||
function initThemeWizard() {
|
||||
var $wizard = $(this);
|
||||
var preLoadBlob = null;
|
||||
|
||||
function getFile() {
|
||||
file_selector = $wizard.find('#header-img')[0];
|
||||
file = file_selector.files[0];
|
||||
return file ? file : preLoadBlob;
|
||||
}
|
||||
|
||||
$wizard.on('click', '.reset', _pd(function() {
|
||||
var $this = $(this),
|
||||
|
@ -16,25 +23,24 @@ $(document).ready(function() {
|
|||
$wizard.on('change', 'input[type="file"]', function() {
|
||||
var $row = $(this).closest('.row');
|
||||
var reader = new FileReader(),
|
||||
file = getFile($row.find('input[type=file]'));
|
||||
file = getFile();
|
||||
if (!file) return; // don't do anything if no file selected.
|
||||
$row.find('input[type=file], .note').hide();
|
||||
|
||||
var $preview_img = $row.find('.preview');
|
||||
|
||||
reader.onload = function(e) {
|
||||
$preview_img.attr('src', e.target.result);
|
||||
$preview_img.show().addClass('loaded');
|
||||
$row.find('.reset').show().css('display', 'block');
|
||||
updateManifest();
|
||||
$row.find('input[type=file], .note').hide();
|
||||
var filename = file.name.replace(/\.[^/.]+$/, "");
|
||||
$wizard.find('a.download').attr('download', filename + ".zip");
|
||||
var name_input = $wizard.find('#theme-name');
|
||||
if (!name_input.val()) {
|
||||
name_input.val(filename);
|
||||
}
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
|
||||
var filename = file.name.replace(/\.[^/.]+$/, "");
|
||||
$wizard.find('a.download').attr('download', filename + ".zip");
|
||||
var name_input = $wizard.find('#theme-name');
|
||||
if (!name_input.val()) {
|
||||
name_input.val(filename);
|
||||
}
|
||||
});
|
||||
$wizard.find('input[type="file"]').trigger('change');
|
||||
|
||||
|
@ -47,6 +53,22 @@ $(document).ready(function() {
|
|||
$svg_img.attr('preserveAspectRatio', 'xMaxYMin '+ meetOrSlice);
|
||||
});
|
||||
|
||||
$wizard.find('#theme-header').each(function(index, element) {
|
||||
var img_src = $(element).data('existing-header');
|
||||
// If we already have a preview from a selected file don't overwrite it.
|
||||
if (getFile() || !img_src) return;
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", img_src);
|
||||
xhr.responseType = "blob";
|
||||
// load the image as a blob so we can treat it as a File
|
||||
xhr.onload = function() {
|
||||
preLoadBlob = xhr.response;
|
||||
preLoadBlob.name = img_src.split('/').slice(-1)[0];
|
||||
$wizard.find('input[type="file"]').trigger('change');
|
||||
};
|
||||
xhr.send();
|
||||
});
|
||||
|
||||
function updateManifest() {
|
||||
textarea = $wizard.find('#manifest').val(generateManifest());
|
||||
toggleSubmitIfNeeded();
|
||||
|
@ -56,13 +78,8 @@ $(document).ready(function() {
|
|||
$wizard.find('button.upload').attr('disabled', ! required_fields_present());
|
||||
}
|
||||
|
||||
function getFile($input) {
|
||||
file_selector = $input[0];
|
||||
return file_selector.files[0];
|
||||
}
|
||||
|
||||
function generateManifest() {
|
||||
var headerFile = getFile($wizard.find('#header-img')),
|
||||
var headerFile = getFile(),
|
||||
headerURL = headerFile ? headerFile.name : "";
|
||||
|
||||
function colVal(id) {
|
||||
|
@ -96,7 +113,7 @@ $(document).ready(function() {
|
|||
function buildZip() {
|
||||
var zip = new JSZip();
|
||||
zip.file('manifest.json', generateManifest());
|
||||
var header_img = getFile($wizard.find('#header-img'));
|
||||
var header_img = getFile();
|
||||
if (header_img) {
|
||||
zip.file(header_img.name, header_img);
|
||||
}
|
||||
|
@ -203,7 +220,7 @@ $(document).ready(function() {
|
|||
|
||||
function required_fields_present() {
|
||||
return $wizard.find('#theme-name').val() !== "" &&
|
||||
$wizard.find('#header-img')[0].files.length > 0 &&
|
||||
getFile() &&
|
||||
$wizard.find('#accentcolor').val() !== "" &&
|
||||
$wizard.find('#textcolor').val() !== "";
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче