allow data-name attribute in texts and use for navigation

This commit is contained in:
j 2013-11-10 22:01:25 +00:00
parent 7dde9eb8ae
commit dca703a4ee
7 changed files with 61 additions and 27 deletions

View file

@ -130,7 +130,7 @@ class Text(models.Model):
elif key == 'description': elif key == 'description':
self.description = ox.sanitize_html(data['description']) self.description = ox.sanitize_html(data['description'])
elif key == 'text': elif key == 'text':
self.text = ox.sanitize_html(data['text']) self.text = ox.sanitize_html(data['text'], global_attributes=['data-name'])
elif key == 'rightslevel': elif key == 'rightslevel':
self.rightslevel = int(data['rightslevel']) self.rightslevel = int(data['rightslevel'])
@ -152,6 +152,7 @@ class Text(models.Model):
self.update_icon() self.update_icon()
def json(self, keys=None, user=None): def json(self, keys=None, user=None):
default_keys = ['id']
if not keys: if not keys:
keys=[ keys=[
'description', 'description',
@ -165,7 +166,10 @@ class Text(models.Model):
'subscribed', 'subscribed',
'text', 'text',
'type', 'type',
'user' 'user',
'uploaded',
'embeds',
'names',
] ]
response = {} response = {}
_map = { _map = {
@ -191,6 +195,10 @@ class Text(models.Model):
response['names'] = [] response['names'] = []
else: else:
response['names'] = re.compile('<[^<>]*?data-name="(.+?)"').findall(self.text) response['names'] = re.compile('<[^<>]*?data-name="(.+?)"').findall(self.text)
for key in response.keys():
if key not in keys + default_keys:
del response[key]
return response return response
def path(self, name=''): def path(self, name=''):

View file

@ -72,7 +72,8 @@ actions.register(addText, cache=False)
def getText(request): def getText(request):
''' '''
takes { takes {
id: textid id: textid,
keys: []
} }
returns { returns {
id: id:
@ -101,7 +102,7 @@ def getText(request):
text = None text = None
response['status']['code'] = 404 response['status']['code'] = 404
if text: if text:
response['data'] = text.json(user=request.user) response['data'] = text.json(user=request.user, keys=data.get('keys'))
return render_to_json_response(response) return render_to_json_response(response)
actions.register(getText) actions.register(getText)

View file

@ -173,8 +173,10 @@ pandora.UI = (function() {
} }
if (args.text) { if (args.text) {
add['texts.' + that.encode(args.text)] = Ox.map(textSettings, function(value, key) { add['texts.' + that.encode(args.text)] = Ox.map(textSettings, function(value, key) {
var textsKey = 'texts.' + that.encode(args.text) + '.' + key; var textsKey = 'texts.' + that.encode(args.text),
return textsKey in args ? args[textsKey] textsSubKey = textsKey + '.' + key;
return textsKey in args && key in args[textsKey] ? args[textsKey][key]
: textsSubKey in args ? args[textSubKey]
: pandora.user.ui.texts[args.text] ? pandora.user.ui.texts[args.text][key] : pandora.user.ui.texts[args.text] ? pandora.user.ui.texts[args.text][key]
: value; : value;
}); });
@ -208,7 +210,7 @@ pandora.UI = (function() {
pandora.api.setUI(set); pandora.api.setUI(set);
} }
triggerEvents && Ox.forEach(trigger, function(val, key) { triggerEvents && Ox.forEach(trigger, function(val, key) {
Ox.Log('UI', 'TRIGGER ' + key + ' ' + val); Ox.Log('UI', 'TRIGGER ', key, val);
Ox.forEach(pandora.$ui, function(element) { Ox.forEach(pandora.$ui, function(element) {
Ox.UI.isElement(element) && element.triggerEvent('pandora_' + key.toLowerCase(), { Ox.UI.isElement(element) && element.triggerEvent('pandora_' + key.toLowerCase(), {
value: val, value: val,

View file

@ -67,7 +67,6 @@ pandora.URL = (function() {
} else if (pandora.user.ui.section == 'texts') { } else if (pandora.user.ui.section == 'texts') {
var textState = pandora.user.ui.texts[state.item] || {}, var textState = pandora.user.ui.texts[state.item] || {},
position = textState.position || 0; position = textState.position || 0;
if (textState.name) { if (textState.name) {
state.span = textState.name; state.span = textState.name;
} else if (position) { } else if (position) {

View file

@ -85,8 +85,10 @@ pandora.ui.mainPanel = function() {
data.value == that.options('elements')[0].collapsed && that.toggle(0); data.value == that.options('elements')[0].collapsed && that.toggle(0);
}, },
pandora_text: function(data) { pandora_text: function(data) {
if (data.value != data.previousValue) {
that.replaceElement(1, pandora.$ui.textPanel = pandora.ui.textPanel()); that.replaceElement(1, pandora.$ui.textPanel = pandora.ui.textPanel());
} }
}
}); });
return that; return that;
}; };

View file

@ -171,8 +171,6 @@ pandora.ui.textPanel = function() {
that.replaceElement(2, $statusbar); that.replaceElement(2, $statusbar);
embedURLs.length && that.selectEmbed(0); embedURLs.length && that.selectEmbed(0);
pandora.user.ui.texts[pandora.user.ui.text] &&
pandora.$ui.text.scrollTo(pandora.user.ui.texts[pandora.user.ui.text].position || 0);
}); });
function getEmbedURLs(text) { function getEmbedURLs(text) {
@ -207,12 +205,14 @@ pandora.ui.textPanel = function() {
}; };
that.update = function(text) { that.update = function(text) {
var index;
embedURLs = getEmbedURLs(text); embedURLs = getEmbedURLs(text);
selected = embedURLs.indexOf(selectedURL); index = embedURLs.indexOf(selectedURL);
if (selected == -1 && embedURLs.length) { if (embedURLs.length && (index == -1 || index >= embedURLs.length)) {
selected = 0; index = 0;
} }
that.selectEmbed(selected); selected = -1;
that.selectEmbed(index);
}; };
return that; return that;
@ -232,15 +232,19 @@ pandora.ui.textHTML = function(text) {
scroll: function(event) { scroll: function(event) {
var position = Math.round(100 * that[0].scrollTop / that[0].scrollHeight) var position = Math.round(100 * that[0].scrollTop / that[0].scrollHeight)
position = position - position % 10; position = position - position % 10;
if (pandora.user.ui.texts[pandora.user.ui.text] if (!scrolling && pandora.user.ui.texts[pandora.user.ui.text]
&& position != pandora.user.ui.texts[pandora.user.ui.text].position) { && position != pandora.user.ui.texts[pandora.user.ui.text].position) {
pandora.UI.set( pandora.UI.set('texts.' + pandora.UI.encode(pandora.user.ui.text), {
'texts.' + pandora.UI.encode(pandora.user.ui.text) + '.position', position: position ? position : 0
position ? position : 0 });
);
}
} }
scrolling = false;
},
})
.bindEvent('pandora_texts.' + text.id.toLowerCase(), function(data) {
data.value && data.value.name && scrollToPosition();
}), }),
scrolling = false,
$content = Ox.Element().css({ $content = Ox.Element().css({
margin: '16px', margin: '16px',
}).appendTo(that), }).appendTo(that),
@ -301,6 +305,7 @@ pandora.ui.textHTML = function(text) {
} }
); );
}, },
globalAttributes: ['data-name'],
placeholder: text.editable ? Ox._('Doubleclick to edit text') : '', placeholder: text.editable ? Ox._('Doubleclick to edit text') : '',
tooltip: text.editable ? pandora.getEditTooltip('text') : '', tooltip: text.editable ? pandora.getEditTooltip('text') : '',
type: 'textarea', type: 'textarea',
@ -339,10 +344,25 @@ pandora.ui.textHTML = function(text) {
- 32 - 16; - 32 - 16;
} }
function scrollTo(position) { function scrollTo(position) {
scrolling = true;
that[0].scrollTop = that[0].scrollHeight/100 * position; that[0].scrollTop = that[0].scrollHeight/100 * position;
} }
function scrollToPosition() {
var settings = pandora.user.ui.texts[pandora.user.ui.text] || {},
position = settings.position || 0,
element,
scrollTop;
if (settings.name) {
element = that.find('*[data-name=' + settings.name + ']');
scrollTop = Math.max(that[0].scrollTop + element.offset().top - 48, 0);
position = 100 * scrollTop / that[0].scrollHeight;
}
scrollTo(position);
}
that.scrollTo = scrollTo; that.scrollTo = scrollTo;
that.update = function() { that.update = function() {
@ -351,8 +371,7 @@ pandora.ui.textHTML = function(text) {
}).css({ }).css({
width: getWidth() + 'px' width: getWidth() + 'px'
}); });
pandora.user.ui.texts[pandora.user.ui.text] && scrollToPosition();
scrollTo(pandora.user.ui.texts[pandora.user.ui.text].position || 0);
return that; return that;
}; };
@ -397,7 +416,9 @@ pandora.ui.textPDF = function(text) {
}); });
}).open(); }).open();
} else if (event == 'page') { } else if (event == 'page') {
pandora.UI.set('texts.' + pandora.UI.encode(pandora.user.ui.text) + '.position', data.page); pandora.UI.set('texts.' + pandora.UI.encode(pandora.user.ui.text), {
'position': data.page
});
} }
}) })
.appendTo(that); .appendTo(that);
@ -407,6 +428,7 @@ pandora.ui.textPDF = function(text) {
} else { } else {
that.html('Please upload PDF'); that.html('Please upload PDF');
} }
return that; return that;
}; };

View file

@ -1112,7 +1112,7 @@ pandora.getItem = function(state, str, callback) {
} }
}); });
} else if (state.type == 'texts') { } else if (state.type == 'texts') {
pandora.api.getText({id: str}, function(result) { pandora.api.getText({id: str, keys: ['id', 'names', 'pages', 'type']}, function(result) {
if (result.status.code == 200) { if (result.status.code == 200) {
state.item = result.data.id; state.item = result.data.id;
callback(); callback();
@ -1528,7 +1528,7 @@ pandora.getSpan = function(state, val, callback) {
}); });
} }
} else if (state.type == 'texts') { } else if (state.type == 'texts') {
pandora.api.getText({id: state.item}, function(result) { pandora.api.getText({id: state.item, keys: ['id', 'names', 'pages', 'type']}, function(result) {
if (isArray) { if (isArray) {
if (result.data.type == 'html') { if (result.data.type == 'html') {
state.span = Ox.limit(val[0], 0, 100); state.span = Ox.limit(val[0], 0, 100);
@ -1925,7 +1925,7 @@ pandora.resizeFolders = function(section) {
}; };
pandora.resizeWindow = function() { pandora.resizeWindow = function() {
if (pandora.$ui.embedPanel) { if (pandora.$ui.embedPanel && pandora.$ui.embedPanel.resizePanel) {
pandora.$ui.embedPanel.resizePanel(); pandora.$ui.embedPanel.resizePanel();
} }
if (pandora.$ui.embedPanel || pandora.$ui.printView) { if (pandora.$ui.embedPanel || pandora.$ui.printView) {