From dca703a4ee7bf6ad8f183da80bb8bca34c464cd7 Mon Sep 17 00:00:00 2001 From: j <0x006A@0x2620.org> Date: Sun, 10 Nov 2013 22:01:25 +0000 Subject: [PATCH] allow data-name attribute in texts and use for navigation --- pandora/text/models.py | 12 ++++++++-- pandora/text/views.py | 5 ++-- static/js/UI.js | 8 ++++--- static/js/URL.js | 1 - static/js/mainPanel.js | 4 +++- static/js/textPanel.js | 52 ++++++++++++++++++++++++++++++------------ static/js/utils.js | 6 ++--- 7 files changed, 61 insertions(+), 27 deletions(-) diff --git a/pandora/text/models.py b/pandora/text/models.py index 52a40047..32ca7b26 100644 --- a/pandora/text/models.py +++ b/pandora/text/models.py @@ -130,7 +130,7 @@ class Text(models.Model): elif key == 'description': self.description = ox.sanitize_html(data['description']) elif key == 'text': - self.text = ox.sanitize_html(data['text']) + self.text = ox.sanitize_html(data['text'], global_attributes=['data-name']) elif key == 'rightslevel': self.rightslevel = int(data['rightslevel']) @@ -152,6 +152,7 @@ class Text(models.Model): self.update_icon() def json(self, keys=None, user=None): + default_keys = ['id'] if not keys: keys=[ 'description', @@ -165,7 +166,10 @@ class Text(models.Model): 'subscribed', 'text', 'type', - 'user' + 'user', + 'uploaded', + 'embeds', + 'names', ] response = {} _map = { @@ -191,6 +195,10 @@ class Text(models.Model): response['names'] = [] else: 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 def path(self, name=''): diff --git a/pandora/text/views.py b/pandora/text/views.py index 9cb89114..4da5c1ff 100644 --- a/pandora/text/views.py +++ b/pandora/text/views.py @@ -72,7 +72,8 @@ actions.register(addText, cache=False) def getText(request): ''' takes { - id: textid + id: textid, + keys: [] } returns { id: @@ -101,7 +102,7 @@ def getText(request): text = None response['status']['code'] = 404 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) actions.register(getText) diff --git a/static/js/UI.js b/static/js/UI.js index fbce6878..8872340d 100644 --- a/static/js/UI.js +++ b/static/js/UI.js @@ -173,8 +173,10 @@ pandora.UI = (function() { } if (args.text) { add['texts.' + that.encode(args.text)] = Ox.map(textSettings, function(value, key) { - var textsKey = 'texts.' + that.encode(args.text) + '.' + key; - return textsKey in args ? args[textsKey] + var textsKey = 'texts.' + that.encode(args.text), + 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] : value; }); @@ -208,7 +210,7 @@ pandora.UI = (function() { pandora.api.setUI(set); } 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.UI.isElement(element) && element.triggerEvent('pandora_' + key.toLowerCase(), { value: val, diff --git a/static/js/URL.js b/static/js/URL.js index f9d86fc9..0f703480 100644 --- a/static/js/URL.js +++ b/static/js/URL.js @@ -67,7 +67,6 @@ pandora.URL = (function() { } else if (pandora.user.ui.section == 'texts') { var textState = pandora.user.ui.texts[state.item] || {}, position = textState.position || 0; - if (textState.name) { state.span = textState.name; } else if (position) { diff --git a/static/js/mainPanel.js b/static/js/mainPanel.js index 478b5c60..ee429d19 100644 --- a/static/js/mainPanel.js +++ b/static/js/mainPanel.js @@ -85,7 +85,9 @@ pandora.ui.mainPanel = function() { data.value == that.options('elements')[0].collapsed && that.toggle(0); }, pandora_text: function(data) { - that.replaceElement(1, pandora.$ui.textPanel = pandora.ui.textPanel()); + if (data.value != data.previousValue) { + that.replaceElement(1, pandora.$ui.textPanel = pandora.ui.textPanel()); + } } }); return that; diff --git a/static/js/textPanel.js b/static/js/textPanel.js index 359698b4..9ae27745 100644 --- a/static/js/textPanel.js +++ b/static/js/textPanel.js @@ -171,8 +171,6 @@ pandora.ui.textPanel = function() { that.replaceElement(2, $statusbar); 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) { @@ -207,12 +205,14 @@ pandora.ui.textPanel = function() { }; that.update = function(text) { + var index; embedURLs = getEmbedURLs(text); - selected = embedURLs.indexOf(selectedURL); - if (selected == -1 && embedURLs.length) { - selected = 0; + index = embedURLs.indexOf(selectedURL); + if (embedURLs.length && (index == -1 || index >= embedURLs.length)) { + index = 0; } - that.selectEmbed(selected); + selected = -1; + that.selectEmbed(index); }; return that; @@ -232,15 +232,19 @@ pandora.ui.textHTML = function(text) { scroll: function(event) { var position = Math.round(100 * that[0].scrollTop / that[0].scrollHeight) 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) { - pandora.UI.set( - 'texts.' + pandora.UI.encode(pandora.user.ui.text) + '.position', - position ? position : 0 - ); + pandora.UI.set('texts.' + pandora.UI.encode(pandora.user.ui.text), { + position: 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({ margin: '16px', }).appendTo(that), @@ -301,6 +305,7 @@ pandora.ui.textHTML = function(text) { } ); }, + globalAttributes: ['data-name'], placeholder: text.editable ? Ox._('Doubleclick to edit text') : '', tooltip: text.editable ? pandora.getEditTooltip('text') : '', type: 'textarea', @@ -339,10 +344,25 @@ pandora.ui.textHTML = function(text) { - 32 - 16; } + function scrollTo(position) { + scrolling = true; 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.update = function() { @@ -351,8 +371,7 @@ pandora.ui.textHTML = function(text) { }).css({ width: getWidth() + 'px' }); - pandora.user.ui.texts[pandora.user.ui.text] && - scrollTo(pandora.user.ui.texts[pandora.user.ui.text].position || 0); + scrollToPosition(); return that; }; @@ -397,7 +416,9 @@ pandora.ui.textPDF = function(text) { }); }).open(); } 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); @@ -407,6 +428,7 @@ pandora.ui.textPDF = function(text) { } else { that.html('Please upload PDF'); } + return that; }; diff --git a/static/js/utils.js b/static/js/utils.js index dc347e4b..68a3d204 100644 --- a/static/js/utils.js +++ b/static/js/utils.js @@ -1112,7 +1112,7 @@ pandora.getItem = function(state, str, callback) { } }); } 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) { state.item = result.data.id; callback(); @@ -1528,7 +1528,7 @@ pandora.getSpan = function(state, val, callback) { }); } } 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 (result.data.type == 'html') { state.span = Ox.limit(val[0], 0, 100); @@ -1925,7 +1925,7 @@ pandora.resizeFolders = function(section) { }; pandora.resizeWindow = function() { - if (pandora.$ui.embedPanel) { + if (pandora.$ui.embedPanel && pandora.$ui.embedPanel.resizePanel) { pandora.$ui.embedPanel.resizePanel(); } if (pandora.$ui.embedPanel || pandora.$ui.printView) {