You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by br...@apache.org on 2016/12/17 21:21:42 UTC
[7/7] jspwiki git commit: Various HADDOCK updates & fixes
Various HADDOCK updates & fixes
See Changelog for details
Project: http://git-wip-us.apache.org/repos/asf/jspwiki/repo
Commit: http://git-wip-us.apache.org/repos/asf/jspwiki/commit/19b54311
Tree: http://git-wip-us.apache.org/repos/asf/jspwiki/tree/19b54311
Diff: http://git-wip-us.apache.org/repos/asf/jspwiki/diff/19b54311
Branch: refs/heads/master
Commit: 19b543113f0f70efcc7e58736d1fd8d529bc3f60
Parents: 014dc67
Author: brushed <di...@gmail.com>
Authored: Sat Dec 17 22:21:21 2016 +0100
Committer: brushed <di...@gmail.com>
Committed: Sat Dec 17 22:21:21 2016 +0100
----------------------------------------------------------------------
ChangeLog | 42 +
jspwiki-war/src/main/config/wro/wro.properties | 4 +-
.../src/main/java/org/apache/wiki/Release.java | 2 +-
.../apache/wiki/plugin/WeblogArchivePlugin.java | 28 +-
.../org/apache/wiki/plugin/WeblogPlugin.java | 20 +-
.../apache/wiki/xmlrpc/MetaWeblogHandler.java | 34 +-
.../resources/plugin/PluginResources.properties | 1 +
.../main/resources/templates/default.properties | 17 +-
.../src/main/scripts/behaviors/Accordion.js | 4 +-
.../src/main/scripts/behaviors/AddCSS.js | 11 +-
.../src/main/scripts/behaviors/Columns.js | 2 +-
jspwiki-war/src/main/scripts/behaviors/Flip.js | 2 +-
.../src/main/scripts/behaviors/GraphBar.js | 3 +-
.../src/main/scripts/behaviors/TableX.js | 5 +-
.../src/main/scripts/behaviors/Viewer.js | 4 +-
.../src/main/scripts/dialog/Dialog.Selection.js | 41 +-
jspwiki-war/src/main/scripts/dialog/Dialog.js | 35 +-
.../scripts/moo-extend/Array.NaturalSort.js | 2 +-
.../src/main/scripts/moo-extend/Behavior.js | 25 +-
.../src/main/scripts/moo-extend/Color.js | 21 +-
.../main/scripts/moo-extend/Element.Extend.js | 2 +-
.../main/scripts/moo-extend/String.Extend.js | 15 +-
.../src/main/scripts/moo-extend/Textarea.js | 9 +
.../main/scripts/wiki-edit/Snipe.Commands.js | 16 +-
.../main/scripts/wiki-edit/Snipe.Sections.js | 150 ++-
.../src/main/scripts/wiki-edit/Snipe.Snips.js | 42 +-
jspwiki-war/src/main/scripts/wiki-edit/Snipe.js | 317 +++---
.../src/main/scripts/wiki-edit/Undoable.js | 7 +-
.../src/main/scripts/wiki-edit/Wiki.Edit.js | 278 +++---
.../src/main/scripts/wiki-edit/Wiki.Snips.js | 962 +++++++++----------
jspwiki-war/src/main/scripts/wiki/Category.js | 4 +-
jspwiki-war/src/main/scripts/wiki/Recents.js | 2 +-
.../src/main/scripts/wiki/Wiki.Behaviors.js | 67 +-
jspwiki-war/src/main/scripts/wiki/Wiki.js | 130 ++-
.../main/styles/haddock/bootstrap/.csscomb.json | 304 ++++++
.../main/styles/haddock/bootstrap/.csslintrc | 19 +
.../main/styles/haddock/bootstrap/alerts.less | 32 +-
.../main/styles/haddock/bootstrap/badges.less | 73 +-
.../styles/haddock/bootstrap/bootstrap.less | 31 +-
.../styles/haddock/bootstrap/breadcrumbs.less | 25 +-
.../styles/haddock/bootstrap/button-groups.less | 91 +-
.../main/styles/haddock/bootstrap/buttons.less | 73 +-
.../main/styles/haddock/bootstrap/carousel.less | 82 +-
.../main/styles/haddock/bootstrap/close.less | 21 +-
.../src/main/styles/haddock/bootstrap/code.less | 38 +-
.../haddock/bootstrap/component-animations.less | 34 +-
.../styles/haddock/bootstrap/dropdowns.less | 69 +-
.../main/styles/haddock/bootstrap/forms.less | 406 ++++++--
.../styles/haddock/bootstrap/glyphicons.less | 112 ++-
.../src/main/styles/haddock/bootstrap/grid.less | 75 +-
.../styles/haddock/bootstrap/input-groups.less | 101 +-
.../styles/haddock/bootstrap/jumbotron.less | 46 +-
.../main/styles/haddock/bootstrap/labels.less | 22 +-
.../styles/haddock/bootstrap/list-group.less | 90 +-
.../main/styles/haddock/bootstrap/media.less | 66 ++
.../main/styles/haddock/bootstrap/mixins.less | 897 +----------------
.../styles/haddock/bootstrap/mixins/alerts.less | 14 +
.../bootstrap/mixins/background-variant.less | 9 +
.../haddock/bootstrap/mixins/border-radius.less | 18 +
.../haddock/bootstrap/mixins/buttons.less | 65 ++
.../haddock/bootstrap/mixins/center-block.less | 7 +
.../haddock/bootstrap/mixins/clearfix.less | 22 +
.../styles/haddock/bootstrap/mixins/forms.less | 85 ++
.../haddock/bootstrap/mixins/gradients.less | 59 ++
.../bootstrap/mixins/grid-framework.less | 91 ++
.../styles/haddock/bootstrap/mixins/grid.less | 122 +++
.../haddock/bootstrap/mixins/hide-text.less | 21 +
.../styles/haddock/bootstrap/mixins/image.less | 33 +
.../styles/haddock/bootstrap/mixins/labels.less | 12 +
.../haddock/bootstrap/mixins/list-group.less | 30 +
.../haddock/bootstrap/mixins/nav-divider.less | 10 +
.../bootstrap/mixins/nav-vertical-align.less | 9 +
.../haddock/bootstrap/mixins/opacity.less | 8 +
.../haddock/bootstrap/mixins/pagination.less | 24 +
.../styles/haddock/bootstrap/mixins/panels.less | 24 +
.../haddock/bootstrap/mixins/progress-bar.less | 10 +
.../haddock/bootstrap/mixins/reset-filter.less | 8 +
.../haddock/bootstrap/mixins/reset-text.less | 18 +
.../styles/haddock/bootstrap/mixins/resize.less | 6 +
.../bootstrap/mixins/responsive-visibility.less | 15 +
.../styles/haddock/bootstrap/mixins/size.less | 10 +
.../haddock/bootstrap/mixins/tab-focus.less | 9 +
.../haddock/bootstrap/mixins/table-row.less | 28 +
.../haddock/bootstrap/mixins/text-emphasis.less | 9 +
.../haddock/bootstrap/mixins/text-overflow.less | 8 +
.../bootstrap/mixins/vendor-prefixes.less | 227 +++++
.../main/styles/haddock/bootstrap/modals.less | 71 +-
.../main/styles/haddock/bootstrap/navbar.less | 154 +--
.../src/main/styles/haddock/bootstrap/navs.less | 28 +-
.../styles/haddock/bootstrap/normalize.less | 318 +++---
.../main/styles/haddock/bootstrap/pager.less | 33 +-
.../styles/haddock/bootstrap/pagination.less | 38 +-
.../main/styles/haddock/bootstrap/panels.less | 217 +++--
.../main/styles/haddock/bootstrap/popovers.less | 56 +-
.../main/styles/haddock/bootstrap/print.less | 216 ++---
.../styles/haddock/bootstrap/progress-bars.less | 37 +-
.../haddock/bootstrap/responsive-embed.less | 35 +
.../haddock/bootstrap/responsive-utilities.less | 253 +++--
.../styles/haddock/bootstrap/scaffolding.less | 72 +-
.../main/styles/haddock/bootstrap/tables.less | 55 +-
.../main/styles/haddock/bootstrap/theme.less | 90 +-
.../styles/haddock/bootstrap/thumbnails.less | 36 +
.../main/styles/haddock/bootstrap/tooltip.less | 42 +-
.../src/main/styles/haddock/bootstrap/type.less | 213 ++--
.../styles/haddock/bootstrap/utilities.less | 21 -
.../styles/haddock/bootstrap/variables.less | 650 ++++++++-----
.../main/styles/haddock/bootstrap/wells.less | 29 +
.../src/main/styles/haddock/default/.crunch | 123 +++
.../main/styles/haddock/default/Calendar.less | 48 -
.../src/main/styles/haddock/default/Dialog.less | 19 +-
.../main/styles/haddock/default/Invisibles.less | 2 +-
.../haddock/default/RecentChangesPlugin.less | 10 +-
.../main/styles/haddock/default/TOCPlugin.less | 20 +-
.../haddock/default/Template.Content.less | 4 +-
.../styles/haddock/default/Template.Edit.less | 147 ++-
.../src/main/styles/haddock/default/Tips.less | 7 +-
.../styles/haddock/default/WeblogPlugin.less | 63 +-
.../src/main/styles/haddock/default/build.less | 13 +-
.../src/main/styles/haddock/default/grid.less | 2 +-
.../main/styles/haddock/default/prettify.less | 14 +-
.../src/main/styles/haddock/default/type.less | 145 ++-
.../main/styles/haddock/default/variables.less | 8 +-
.../main/styles/haddock/fontjspwiki/core.less | 13 +-
.../main/styles/haddock/fontjspwiki/path.less | 13 +-
jspwiki-war/src/main/webapp/Comment.jsp | 3 +-
jspwiki-war/src/main/webapp/DeleteGroup.jsp | 11 +-
jspwiki-war/src/main/webapp/Install.jsp | 62 +-
.../src/main/webapp/XHRMarkup2Wysiwyg.jsp | 84 ++
.../webapp/templates/haddock/AttachmentTab.jsp | 2 +-
.../webapp/templates/haddock/CommentContent.jsp | 18 +-
.../main/webapp/templates/haddock/DiffTab.jsp | 2 +-
.../webapp/templates/haddock/EditTemplate.jsp | 2 +-
.../main/webapp/templates/haddock/Header.jsp | 2 +-
.../webapp/templates/haddock/InfoContent.jsp | 2 +-
.../src/main/webapp/templates/haddock/Nav.jsp | 15 +-
.../main/webapp/templates/haddock/PageTab.jsp | 2 -
.../webapp/templates/haddock/PreferencesTab.jsp | 21 +-
.../webapp/templates/haddock/ProfileTab.jsp | 10 +-
.../main/webapp/templates/haddock/Sidebar.jsp | 8 +-
.../webapp/templates/haddock/ViewTemplate.jsp | 3 +-
.../webapp/templates/haddock/commonheader.jsp | 11 +-
.../templates/haddock/editors/CKeditor.jsp | 65 +-
.../templates/haddock/editors/TinyMCE.jsp | 64 +-
.../webapp/templates/haddock/editors/plain.jsp | 183 ++--
.../templates/haddock/editors/wysiwyg.jsp | 74 +-
145 files changed, 5846 insertions(+), 4135 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/ChangeLog
----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index 6b998e8..04ba4cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,47 @@
2016-12-13 Dirk Frederickx (brushed AT apache DOT org)
+ * 2.10.3-svn-20 Various HADDOCK updates & fixes.
+
+ * JSPWiki BLOGS
+ Final update of the styling of JSPWiki's BLOGs.
+ Also the fancy weblog calendar is now back in the sidebar
+ when viewing a blog post.
+
+ * Add-Comment JSP refactored:
+ When adding a comment to a wiki-page, you will see the content of the main page
+ at the top of the editing screen, so you know what your are commenting on.
+ Improved hover menu on the SAVE/POST button for entering the change-note and
+ comment-signature fields.
+
+ * Plain Editor:
+ Many JS improvements related to the handling of text snippets.
+ Several style updates to the editor and the auto-suggest dialogs.
+
+ * Small refactoring of the Install.jsp to fit the bootstrap framework.
+
+ * %%columns-<width>: fix the broken width parameter
+
+ * %%graphbars: fix support for HTML-color-names (chrome, FF)
+
+ * [JSPWIKI-979]: fix support for %%small {{{ preformatted text blocks }}}
+
+ * [JSPWIKI-937]: fix handling of broken image links (also for FF)
+ Fix for rendering of the attachement icon, e.g. in RecentChanges page.
+
+ * Improved visualisation of interwiki links for Edit, Raw, Reader and Groups.
+
+ * The Delete group command now gets you back to the Group view pages, so it is
+ easier for issuing subsequent group commands. (create,edit,delete)
+
+ * Added %%maps to generate google maps viewer by simply including the address.
+
+ * Few html5 FORM improvements: required fields, email input type, ...
+
+ * Updated to bootstrap 3.3.7.
+
+
+2016-12-13 Dirk Frederickx (brushed AT apache DOT org)
+
* 2.10.3-svn-19
* JSPWIKI-1032 : Use image "src" attribute instead of "href"
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/config/wro/wro.properties
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/config/wro/wro.properties b/jspwiki-war/src/main/config/wro/wro.properties
index 1818c10..7c810dc 100644
--- a/jspwiki-war/src/main/config/wro/wro.properties
+++ b/jspwiki-war/src/main/config/wro/wro.properties
@@ -21,5 +21,5 @@ debug=true
#preProcessors=cssUrlRewriting,cssImport,semicolonAppender
preProcessors=cssImport,semicolonAppender
-postProcessors=lessCss,yuiCssMin,uglifyJs
-#postProcessors=less4j.less,cssCompressor,uglifyJs
+#postProcessors=lessCss,yuiCssMin,uglifyJs
+postProcessors=less4j,yuiCssMin,uglifyJs
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/java/org/apache/wiki/Release.java
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/java/org/apache/wiki/Release.java b/jspwiki-war/src/main/java/org/apache/wiki/Release.java
index 5b3584d..b37ef14 100644
--- a/jspwiki-war/src/main/java/org/apache/wiki/Release.java
+++ b/jspwiki-war/src/main/java/org/apache/wiki/Release.java
@@ -72,7 +72,7 @@ public final class Release {
* <p>
* If the build identifier is empty, it is not added.
*/
- public static final String BUILD = "19";
+ public static final String BUILD = "20";
/**
* This is the generic version string you should use when printing out the version. It is of
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/java/org/apache/wiki/plugin/WeblogArchivePlugin.java
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/java/org/apache/wiki/plugin/WeblogArchivePlugin.java b/jspwiki-war/src/main/java/org/apache/wiki/plugin/WeblogArchivePlugin.java
index 1edd903..ef303ed 100644
--- a/jspwiki-war/src/main/java/org/apache/wiki/plugin/WeblogArchivePlugin.java
+++ b/jspwiki-war/src/main/java/org/apache/wiki/plugin/WeblogArchivePlugin.java
@@ -1,4 +1,4 @@
-/*
+/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
@@ -14,7 +14,7 @@
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
- under the License.
+ under the License.
*/
package org.apache.wiki.plugin;
@@ -45,7 +45,7 @@ import org.apache.wiki.util.TextUtil;
* <ul>
* <li><b>page</b> - the page name</li>
* </ul>
- *
+ *
* @since 1.9.21
*/
public class WeblogArchivePlugin implements WikiPlugin
@@ -71,7 +71,7 @@ public class WeblogArchivePlugin implements WikiPlugin
String weblogName = params.get( PARAM_PAGE );
if( weblogName == null ) weblogName = context.getPage().getName();
-
+
m_monthUrlFormat = new SimpleDateFormat("'"+
context.getURL( WikiContext.VIEW, weblogName,
@@ -80,7 +80,7 @@ public class WeblogArchivePlugin implements WikiPlugin
StringBuilder sb = new StringBuilder();
sb.append( "<div class=\"weblogarchive\">\n" );
-
+
//
// Collect months that have blog entries
@@ -123,7 +123,6 @@ public class WeblogArchivePlugin implements WikiPlugin
}
sb.append( "</ul>\n" );
- sb.append( "</div>\n" );
}
catch( ProviderException ex )
{
@@ -131,6 +130,8 @@ public class WeblogArchivePlugin implements WikiPlugin
sb.append("Cannot get archive: "+ex.getMessage());
}
+ sb.append( "</div>\n" );
+
return sb.toString();
}
@@ -143,9 +144,9 @@ public class WeblogArchivePlugin implements WikiPlugin
WeblogPlugin pl = new WeblogPlugin();
- List blogEntries = pl.findBlogEntries( engine.getPageManager(),
+ List blogEntries = pl.findBlogEntries( engine,
page, new Date(0L), new Date() );
-
+
for( Iterator i = blogEntries.iterator(); i.hasNext(); )
{
WikiPage p = (WikiPage) i.next();
@@ -188,7 +189,7 @@ public class WeblogArchivePlugin implements WikiPlugin
}
-
+
/**
* This is a simple comparator for ordering weblog archive entries.
* Two dates in the same month are considered equal.
@@ -197,14 +198,14 @@ public class WeblogArchivePlugin implements WikiPlugin
implements Comparator
{
- public int compare( Object a, Object b )
+ public int compare( Object a, Object b )
{
- if( a == null || b == null ||
+ if( a == null || b == null ||
!(a instanceof Calendar) || !(b instanceof Calendar) )
{
throw new ClassCastException( "Invalid calendar supplied for comparison." );
}
-
+
Calendar ca = (Calendar) a;
Calendar cb = (Calendar) b;
if( ca.get( Calendar.YEAR ) == cb.get( Calendar.YEAR ) &&
@@ -213,7 +214,8 @@ public class WeblogArchivePlugin implements WikiPlugin
return 0;
}
- return cb.getTime().before( ca.getTime() ) ? 1 : -1;
+ //sort recent dates first
+ return cb.getTime().before( ca.getTime() ) ? -1 : 1;
}
}
}
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/java/org/apache/wiki/plugin/WeblogPlugin.java
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/java/org/apache/wiki/plugin/WeblogPlugin.java b/jspwiki-war/src/main/java/org/apache/wiki/plugin/WeblogPlugin.java
index d134900..48685ff 100644
--- a/jspwiki-war/src/main/java/org/apache/wiki/plugin/WeblogPlugin.java
+++ b/jspwiki-war/src/main/java/org/apache/wiki/plugin/WeblogPlugin.java
@@ -30,6 +30,7 @@ import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
@@ -268,7 +269,7 @@ public class WeblogPlugin
try
{
- List<WikiPage> blogEntries = findBlogEntries( engine.getPageManager(),
+ List<WikiPage> blogEntries = findBlogEntries( engine,
weblogName,
startTime.getTime(),
stopTime.getTime() );
@@ -375,7 +376,7 @@ public class WeblogPlugin
author = "AnonymousCoward";
}
- buffer.append("By "+author+" ");
+ buffer.append( MessageFormat.format( rb.getString("weblogentryplugin.postedby"), author));
buffer.append( "<a href=\""+entryCtx.getURL(WikiContext.VIEW, entry.getName())+"\">"+rb.getString("weblogentryplugin.permalink")+"</a>" );
String commentPageName = TextUtil.replaceString( entry.getName(),
"blogentry",
@@ -428,35 +429,34 @@ public class WeblogPlugin
* Attempts to locate all pages that correspond to the
* blog entry pattern. Will only consider the days on the dates; not the hours and minutes.
*
- * @param mgr A PageManager which is used to get the pages
+ * @param engine WikiEngine which is used to get the pages
* @param baseName The basename (e.g. "Main" if you want "Main_blogentry_xxxx")
* @param start The date which is the first to be considered
* @param end The end date which is the last to be considered
* @return a list of pages with their FIRST revisions.
* @throws ProviderException If something goes wrong
*/
- public List findBlogEntries( PageManager mgr,
+ public List findBlogEntries( WikiEngine engine,
String baseName, Date start, Date end )
throws ProviderException
{
- Collection everyone = mgr.getAllPages();
+ PageManager mgr = engine.getPageManager();
+ Set allPages = engine.getReferenceManager().findCreated();
+
ArrayList<WikiPage> result = new ArrayList<WikiPage>();
baseName = makeEntryPage( baseName );
SimpleDateFormat fmt = new SimpleDateFormat(DEFAULT_DATEFORMAT);
- for( Iterator i = everyone.iterator(); i.hasNext(); )
+ for( Iterator i = allPages.iterator(); i.hasNext(); )
{
- WikiPage p = (WikiPage)i.next();
-
- String pageName = p.getName();
+ String pageName = (String)i.next();
if( pageName.startsWith( baseName ) )
{
try
{
WikiPage firstVersion = mgr.getPageInfo( pageName, 1 );
-
Date d = firstVersion.getLastModified();
if( d.after(start) && d.before(end) )
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/java/org/apache/wiki/xmlrpc/MetaWeblogHandler.java
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/java/org/apache/wiki/xmlrpc/MetaWeblogHandler.java b/jspwiki-war/src/main/java/org/apache/wiki/xmlrpc/MetaWeblogHandler.java
index ff2c045..42acb4e 100644
--- a/jspwiki-war/src/main/java/org/apache/wiki/xmlrpc/MetaWeblogHandler.java
+++ b/jspwiki-war/src/main/java/org/apache/wiki/xmlrpc/MetaWeblogHandler.java
@@ -1,4 +1,4 @@
-/*
+/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
@@ -14,7 +14,7 @@
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
- under the License.
+ under the License.
*/
package org.apache.wiki.xmlrpc;
@@ -56,10 +56,10 @@ import org.apache.xmlrpc.XmlRpcException;
public class MetaWeblogHandler
implements WikiRPCHandler
{
- private static Logger log = Logger.getLogger( MetaWeblogHandler.class );
+ private static Logger log = Logger.getLogger( MetaWeblogHandler.class );
private WikiContext m_context;
-
+
/**
* {@inheritDoc}
*/
@@ -87,13 +87,13 @@ public class MetaWeblogHandler
{
AuthenticationManager amm = m_context.getEngine().getAuthenticationManager();
AuthorizationManager mgr = m_context.getEngine().getAuthorizationManager();
-
+
if( amm.login( m_context.getWikiSession(), m_context.getHttpRequest(), username, password ) )
{
if( !mgr.checkPermission( m_context.getWikiSession(), PermissionFactory.getPagePermission( page, permission ) ))
{
throw new XmlRpcException( 1, "No permission" );
- }
+ }
}
else
{
@@ -110,7 +110,7 @@ public class MetaWeblogHandler
/**
* JSPWiki does not support categories, therefore JSPWiki
* always returns an empty list for categories.
- *
+ *
* @param blogid The id of the blog.
* @param username The username to use
* @param password The password
@@ -165,7 +165,7 @@ public class MetaWeblogHandler
{
title = pageText.substring( 0, firstLine );
}
-
+
if( title.trim().length() == 0 ) title = page.getName();
// Remove wiki formatting
@@ -179,7 +179,7 @@ public class MetaWeblogHandler
/**
* Returns a list of the recent posts to this weblog.
- *
+ *
* @param blogid The id of the blog.
* @param username The username to use
* @param password The password
@@ -210,7 +210,7 @@ public class MetaWeblogHandler
{
WeblogPlugin plugin = new WeblogPlugin();
- List<WikiPage> changed = plugin.findBlogEntries(m_context.getEngine().getPageManager(),
+ List<WikiPage> changed = plugin.findBlogEntries(m_context.getEngine(),
blogid,
new Date(0L),
new Date());
@@ -238,13 +238,13 @@ public class MetaWeblogHandler
/**
* Adds a new post to the blog.
- *
+ *
* @param blogid The id of the blog.
* @param username The username to use
* @param password The password
* @param content As per Metaweblogapi contract
* @param publish This parameter is ignored for JSPWiki.
- * @return Returns an empty string
+ * @return Returns an empty string
* @throws XmlRpcException If something goes wrong
*/
public String newPost( String blogid,
@@ -256,7 +256,7 @@ public class MetaWeblogHandler
{
log.info("metaWeblog.newPost() called");
WikiEngine engine = m_context.getEngine();
-
+
WikiPage page = engine.getPage( blogid );
checkPermissions( page, username, password, "createPages" );
@@ -293,16 +293,16 @@ public class MetaWeblogHandler
* Creates an attachment and adds it to the blog. The attachment
* is created into the main blog page, not the actual post page,
* because we do not know it at this point.
- *
+ *
* @param blogid The id of the blog.
* @param username The username to use
* @param password The password
* @param content As per the MetaweblogAPI contract
- * @return As per the MetaweblogAPI contract
+ * @return As per the MetaweblogAPI contract
* @throws XmlRpcException If something goes wrong
- *
+ *
*/
- public Hashtable newMediaObject( String blogid,
+ public Hashtable newMediaObject( String blogid,
String username,
String password,
Hashtable content )
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/resources/plugin/PluginResources.properties
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/resources/plugin/PluginResources.properties b/jspwiki-war/src/main/resources/plugin/PluginResources.properties
index ad61c39..4902ef5 100644
--- a/jspwiki-war/src/main/resources/plugin/PluginResources.properties
+++ b/jspwiki-war/src/main/resources/plugin/PluginResources.properties
@@ -46,6 +46,7 @@ currenttimeplugin.badformat = You specified a bad format
# WeblogEntryPlugin
weblogentryplugin.newentry = <span class="icon-plus"></span> New entry
+weblogentryplugin.postedby = Posted by {0}
weblogentryplugin.permalink = Permalink
weblogentryplugin.addcomment = <span class="icon-plus"></span> Add new comment ({0})
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/resources/templates/default.properties
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/resources/templates/default.properties b/jspwiki-war/src/main/resources/templates/default.properties
index 2ce3437..3583e28 100644
--- a/jspwiki-war/src/main/resources/templates/default.properties
+++ b/jspwiki-war/src/main/resources/templates/default.properties
@@ -516,10 +516,11 @@ view.title.view={0}: {1}
# The built-in editors also have their localized strings in this file.
-editor.plain.name=Your <span class='accesskey'>n</span>ame
+editor.plain.name=Name
editor.plain.remember=Remember me?
-editor.plain.email=Homepage or email
+editor.plain.email=Link to homepage or email
editor.plain.save.submit=Save
+editor.plain.save.submit.comment=Post Comment
editor.plain.save.title=Save [ s ]
editor.plain.preview.submit=Preview
editor.plain.preview.title=Preview [ v ]
@@ -558,6 +559,7 @@ editor.plain.sneakpreview.title=Sneak Preview. \
Click outside the textarea to refresh the sneak preview area.
editor.plain.sidebysidepreview=Side by Side Preview
editor.plain.edit.resize=Drag to resize the text and preview area
+editor.plain.comment.resize=Drag to resize the main page area
editor.plain.tbLink.title=link - Insert wiki link
editor.plain.tbH1.title=h1 - Insert heading1
@@ -604,6 +606,7 @@ blog.permalink=Permalink
#
# The Javascript stuff
#
+javascript.broken.image=Content unavailable! (broken link)
javascript.sbox.clearrecent=Clear Recent Searches
javascript.sbox.clone =Clone this page
javascript.sbox.create =Create {0}
@@ -616,6 +619,16 @@ javascript.edit.toolbar.makeSelection=Please make first a selection.
javascript.edit.resize=Drag to resize the text area
javascript.edit.areyousure=Without clicking the Save button, your changes will be lost. \
Are you sure you want to exit this page?
+javascript.preview.zone = Preview Zone
+
+javascript.dialog.character.entities = Character entities
+javascript.dialog.link.attributes = Wiki Link Attributes
+javascript.dialog.plugin = Plugin
+javascript.dialog.permission = Page Permission
+javascript.dialog.principal = Roles, Groups or Users
+javascript.dialog.styles = Additional Styles
+javascript.dialog.toc.options = TOC options
+
javascript.favs.show=Click to show Favorites
javascript.favs.hide=Click to hide Favorites
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/behaviors/Accordion.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/behaviors/Accordion.js b/jspwiki-war/src/main/scripts/behaviors/Accordion.js
index 8b24b9d..3f3fa74 100644
--- a/jspwiki-war/src/main/scripts/behaviors/Accordion.js
+++ b/jspwiki-war/src/main/scripts/behaviors/Accordion.js
@@ -131,8 +131,8 @@ var Accordion = new Class({
}
- toggles.push( toggle );
- contents.push( "div".slick().wraps( pane.addClass("panel-body") ) );
+ toggles[toggles.length] = toggle;
+ contents[contents.length] = "div".slick().wraps( pane.addClass("panel-body") );
}
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/behaviors/AddCSS.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/behaviors/AddCSS.js b/jspwiki-war/src/main/scripts/behaviors/AddCSS.js
index 2a8c8b5..3e3eb28 100644
--- a/jspwiki-war/src/main/scripts/behaviors/AddCSS.js
+++ b/jspwiki-war/src/main/scripts/behaviors/AddCSS.js
@@ -35,7 +35,8 @@ function AddCSS( element ){
function insertStyle ( elements ){
- var css = "", item;
+ var css = "",
+ item;
//collect all css to be inserted
while( item = elements.shift() ){ css += item.innerHTML; }
@@ -45,6 +46,11 @@ function AddCSS( element ){
//magic to replace the inline wiki-image links to css url()
//xss protection: remove invalid url's; only allow url([wiki-attachement])
+
+ //tocheck: allow attached font files <a class=attachment href=xxx.woff><a class=infolink ....>
+ css = css.replace( /url\(<a class="attachment" href="([^"]+.woff)".*><\/a>\)/gi,'url(<ifont href="$1"/>)' );
+ css = css.replace( /url\(<a class="attachment" href="([^"]+.ttf)".*><\/a>\)/gi,'url(<ifont href="$1"/>)' );
+
css = css.replace( /url\(\<[^i][^)]*\)/gi, "url(invalid)" ); //remove url(<a...)
css = css.replace( /url\([^<][^)]*\)/gi, "url(invalid)" ); //remove url(xxx)
@@ -55,9 +61,10 @@ function AddCSS( element ){
css = css.replace( /@imp@rt/g, "@import url(https://fonts.googleapis.com/css?family=");
//xss protection: remove IE dynamic properties
- css = css.replace( /expression|behavior/gi,"invalid" );
+ css = css.replace( /expression|behavior/gi, "invalid" );
css = css.replace( /url\(<img class="inline" .*?src="([^"]+)[^>]*>\)/gi, "url($1)" );
+ css = css.replace( /url\(<ifont href="([^"]+)"\/>\)/gi, "url($1)" );
css = css.replace( /<p>|<\/p>/gi, "" ); //jspwiki inserts <p/> for empty lines
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/behaviors/Columns.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/behaviors/Columns.js b/jspwiki-war/src/main/scripts/behaviors/Columns.js
index 881c117..5bada6c 100644
--- a/jspwiki-war/src/main/scripts/behaviors/Columns.js
+++ b/jspwiki-war/src/main/scripts/behaviors/Columns.js
@@ -56,7 +56,7 @@ function Columns(element, options){
if( columnCount /*>0*/ ){
columnCount++;
- width = ( args[0] ) ? args[0] / columnCount + "px" : 100 / columnCount + "%";
+ width = args[0] ? args[0] + "px" : 100 / columnCount + "%";
element
.addClass("columns")
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/behaviors/Flip.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/behaviors/Flip.js b/jspwiki-war/src/main/scripts/behaviors/Flip.js
index 87073a7..e695124 100644
--- a/jspwiki-war/src/main/scripts/behaviors/Flip.js
+++ b/jspwiki-war/src/main/scripts/behaviors/Flip.js
@@ -52,7 +52,7 @@ function Flip(element, options){
arg = args.pop();
if( !arg.indexOf("w") /*index==0*/ ){ css.width = arg.slice(1).toInt(); }
else if( !arg.indexOf("h") /*index==0*/ ){ css.height = arg.slice(1).toInt(); }
- else if( arg.test(/none|default|success|info|warning|danger/ )){ frontback.push(arg); }
+ else if( arg.test(/none|default|success|info|warning|danger/ )){ frontback[frontback.length] = arg; }
}
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/behaviors/GraphBar.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/behaviors/GraphBar.js b/jspwiki-war/src/main/scripts/behaviors/GraphBar.js
index 1443539..f17374b 100644
--- a/jspwiki-war/src/main/scripts/behaviors/GraphBar.js
+++ b/jspwiki-war/src/main/scripts/behaviors/GraphBar.js
@@ -136,8 +136,8 @@ var GraphBar = new Class({
}
+ //console.log(data, options.minv, options.maxv);
data = data.scale(options.minv, options.maxv)
- console.log(data);
for( i = 0; i < len; i++){
@@ -245,6 +245,7 @@ var GraphBar = new Class({
[offset + size, val + "%", (100 - val) + "%"] :
[offset + val / 100 * (/*offset + */ size), "100%" ];
+
//then convert sizes to bar css styles
css = css.map( function(barsize){
return options.isHorizontal ? {width: barsize} : {height: barsize, width: 20, "vertical-align":"text-bottom"};
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/behaviors/TableX.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/behaviors/TableX.js b/jspwiki-war/src/main/scripts/behaviors/TableX.js
index 55d6cb1..2e2735a 100644
--- a/jspwiki-war/src/main/scripts/behaviors/TableX.js
+++ b/jspwiki-war/src/main/scripts/behaviors/TableX.js
@@ -102,9 +102,10 @@ var TableX = new Class({
if( $(r.cells[col]).get('text').trim() == fieldName ){
//take this COLUMN
- for( i=1; i < tlen; i++)
+ for( i=1; i < tlen; i++){
//result.push( new Element('span').wraps(table.rows[i].cells[col]) );
- result.push( rows[i].cells[col] );
+ result[result.length] = rows[i].cells[col];
+ }
return result;
}
}
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/behaviors/Viewer.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/behaviors/Viewer.js b/jspwiki-war/src/main/scripts/behaviors/Viewer.js
index 494eb9f..f28db02 100644
--- a/jspwiki-war/src/main/scripts/behaviors/Viewer.js
+++ b/jspwiki-war/src/main/scripts/behaviors/Viewer.js
@@ -48,7 +48,6 @@ this.Viewer = {
var result = {};
if( typeOf(url) == "element" ){ url = url.src || url.href; }
-
this.LIB.some( function(item){
return url.test( item[0], "i" )
@@ -62,7 +61,6 @@ this.Viewer = {
//console.log(options.type);
if( options.type && !result[options.type] ){ return false; }
-
return result;
},
@@ -134,7 +132,7 @@ this.Viewer = {
h = options.height;
function preloadCallback(preload, width, height){
- preloads.push( preload );
+ preloads[preloads.length] = preload ;
w = w.max(width);
h = h.max(height.toInt());
//console.log("preloads.length, w,h);
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/dialog/Dialog.Selection.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/dialog/Dialog.Selection.js b/jspwiki-war/src/main/scripts/dialog/Dialog.Selection.js
index f11146f..ac4a89a 100644
--- a/jspwiki-war/src/main/scripts/dialog/Dialog.Selection.js
+++ b/jspwiki-war/src/main/scripts/dialog/Dialog.Selection.js
@@ -70,9 +70,16 @@ Dialog.Selection = new Class({
initialize:function( options ){
- this.setClass(".selection",options);
- this.selected = options.selected || "";
- this.parent( options );
+ var self = this;
+
+ self.setClass(".selection",options);
+ self.selected = options.selected || "";
+ self.parent( options );
+
+ self.element.addEvent("click:relay(.item)", function(e){
+ e.stop();
+ self.action( this.get("title") );
+ });
//console.log("Dialog.Selection ", this.element.className);
},
@@ -107,14 +114,9 @@ Dialog.Selection = new Class({
if( typeOf( content ) == "element" ){
- //first move the content elements into the body and highlight the selected item
- self.parent( content ).setValue( self.selected );
-
- //then add the click & hover event handlers
- self.element.addEvent("click:relay(.item)", function(e){
- e.stop();
- self.action( this.get("title") );
- });
+ //first move the content elements into the body and then highlight the selected item
+ self.parent( content )
+ .setValue( self.selected );
}
@@ -128,13 +130,24 @@ Dialog.Selection = new Class({
*/
setValue: function( value ){
- var self = this, selected = "selected", element;
+ var self = this, selected = "selected", element,
+ target = ".item[title" + self.options.match + value + "]";
+
+ /*ffs
+ if( self.hasClass("dialog-filtered") ){
+ if( value == "" ){
+ this.element.getElements(".item,.divider").show();
+ } else {
+ this.element.getElements(".item,.divider").hide();
+ this.element.getElements(target).show();
+ }
+ }
+ */
element = self.get("." + selected);
if( element ){ element.removeClass(selected); }
- //console.log("Dialog.Selection setValue", value);
- element = self.get( ".item[title" + self.options.match + value + "]" );
+ element = self.get( target );
if( element ){ element.addClass(selected); }
self[selected] = value;
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/dialog/Dialog.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/dialog/Dialog.js b/jspwiki-war/src/main/scripts/dialog/Dialog.js
index 4d23e79..145b547 100644
--- a/jspwiki-war/src/main/scripts/dialog/Dialog.js
+++ b/jspwiki-war/src/main/scripts/dialog/Dialog.js
@@ -111,17 +111,17 @@ var Dialog = new Class({
var self = this, el;
- this.setClass(".dialog",options);
+ this.setClass(".dialog", options);
this.setOptions( options );
- console.log("Dialog.initialize" );
+ //console.log("Dialog.initialize" );
options = self.options;
el = self.element = options.dialog || self.build(options);
el.getElements(".close").addEvent("click", self.hide.bind(self) );
- //make dialog draggable; only possible when el is position absolute
+ //make dialog draggable; only possible when el has an absolute position
if( (el.getStyle("position") == "absolute") && options.draggable ){
new Drag(el,{
@@ -132,7 +132,6 @@ var Dialog = new Class({
self[ options.showNow ? "show": "hide"]();
-
},
toElement: function(){
@@ -154,10 +153,22 @@ var Dialog = new Class({
},
+ hasClass: function(clazz){
+ return this.element.hasClass(clazz);
+ },
+
+ ifClass: function(flag, trueClass, falseClass){
+
+ var body = this.element;
+ if( body ){ body.ifClass(flag, trueClass, falseClass); }
+ return this;
+
+ },
+
setClass: function(clazz, options){
+ console.log("Dialog.setClass", options.cssClass );
options.cssClass = clazz + (options.cssClass || "");
- console.log("Dialog.setClass ", options.cssClass );
},
@@ -213,25 +224,15 @@ var Dialog = new Class({
},
- /*
- Function: action
- Fires the ""action"" event.
- When the autoClose option is set, the dialog will also be hidden.
- */
action: function(value){
- console.log("Dialog action: ",value," close:"+this.options.autoClose);
+ //console.log("Dialog action: ",value," close:"+this.options.autoClose);
this.fireEvent("action", value);
if( this.options.autoClose ){ this.hide(); }
},
- /*
- Function: build
- Build new dialog frame based on caption and body options.
- */
build: function( options ){
- console.log("DIALOG build ",options.cssClass, options.styles);
-
+ //console.log("DIALOG build ",options.cssClass, options.styles);
var element = this.element = [
"div" + options.cssClass, {styles: options.styles}, [
"a.close",{ html: "×"},
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/moo-extend/Array.NaturalSort.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/moo-extend/Array.NaturalSort.js b/jspwiki-war/src/main/scripts/moo-extend/Array.NaturalSort.js
index f7baac8..d91185c 100644
--- a/jspwiki-war/src/main/scripts/moo-extend/Array.NaturalSort.js
+++ b/jspwiki-war/src/main/scripts/moo-extend/Array.NaturalSort.js
@@ -138,7 +138,7 @@ Array.implement({
}
- //console.log("[", kmgt ? "kmgt" : dmy ? "dmy" : num ? "num" : nat ? "nat" : "no conversion", "] ");
+ console.log("[", kmgt ? "kmgt" : dmy ? "dmy" : num ? "num" : nat ? "nat" : "no conversion", "] ");
return kmgt || dmy || num || nat || this.slice();
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/moo-extend/Behavior.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/moo-extend/Behavior.js b/jspwiki-war/src/main/scripts/moo-extend/Behavior.js
index bff1dab..e022326 100644
--- a/jspwiki-war/src/main/scripts/moo-extend/Behavior.js
+++ b/jspwiki-war/src/main/scripts/moo-extend/Behavior.js
@@ -65,11 +65,12 @@ var Behavior = new Class({
update: function(){
var cache = "_bhvr", updated, type, isClass, isFunction,
- nodes, node, i = 0, j, item, behavior, options;
+ nodes, node, i = 0, j, item, behavior, options, items;
while( item = this.behaviors[ i++ ] ){
//console.log("BEHAVIOR ", item.once?"ONCE ":"", nodes.length, item.s, typeOf(item.b) );
+ once = [];
options = item.o;
behavior = item.b;
type = typeOf(behavior);
@@ -80,27 +81,33 @@ var Behavior = new Class({
if( nodes[0] ){
- if( item.once ){
+ for( j=0; node = nodes[ j++ ]; ){
- if( isClass ){ new behavior(nodes, options); }
- else if( isFunction ){ behavior(nodes, options); }
+ updated = node[cache] || (node[cache] = []);
- } else {
+ if ( updated.indexOf(item) < 0 ){
- for( j=0; node = nodes[ j++ ]; ){
+ if( item.once ){
- updated = node[cache] || (node[cache] = []);
+ once.push( node );
- if ( updated.indexOf(item) < 0 ){
+ } else {
//if( isString ) node[behavior](options);
if( isClass ){ new behavior(node, options); }
else if( isFunction ){ behavior.call(node, node, options); }
- updated.push( item );
}
+ updated.push( item );
}
}
+
+ if( once[0] ){
+ //console.log("ONCE", item.s , once.length);
+ if( isClass ){ new behavior($$(once), options); }
+ else if( isFunction ){ behavior($$(once), options); }
+
+ }
}
}
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/moo-extend/Color.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/moo-extend/Color.js b/jspwiki-war/src/main/scripts/moo-extend/Color.js
index c953146..3b0dc05 100644
--- a/jspwiki-war/src/main/scripts/moo-extend/Color.js
+++ b/jspwiki-war/src/main/scripts/moo-extend/Color.js
@@ -24,7 +24,7 @@ Class: Color
This is a minimized variant of the Color class, based Mootools.More,
written for jspwiki.
It adds supports for html color names. (ref. http://en.wikipedia.org/wiki/Web_colors)
-�
+
Arguments:
color - (mixed) A string or an array representation of a color.
@@ -47,9 +47,7 @@ Examples:
!function(){
-var VGA = "black#000 green#008000 silver#c0c0c0 lime#0f0 gray#808080 olive#808000 white#fff yellow#ff0 maroon#800000 navy#000080 red#f00 blue#00f purple#800080 teal#008080 fuchsia#f0f aqua#0ff",
- c0l0r = 'i'.slick(),
-
+var c0l0r = 'i'.slick(),
Color = this.Color = new Type('Color', function(color){
if (arguments.length >= 3){
@@ -58,16 +56,16 @@ var VGA = "black#000 green#008000 silver#c0c0c0 lime#0f0 gray#808080 olive#80800
} else if (typeof color == 'string'){
- if(color.test(/^[\da-f]{3,6}$/i)){ color = "#"+color; }
- c0l0r.setStyle('color',''); //reset the template
- color = ( VGA.test( RegExp(color+"(#\\S+)","i" ) ) ? RegExp.$1 :
- color.match(/rgb/i) ? color.rgbToHex() :
- c0l0r.setStyle('color',color).getStyle('color') ).hexToRgb(true);
+ c0l0r.inject(document.body);
+ color = ( color.test(/^[\da-f]{3,6}$/i) ? ("#" + color) :
+ c0l0r.setStyle('color',color).getComputedStyle('color').rgbToHex() ).hexToRgb(true); //[r,g,b]
+ c0l0r.remove();
}
if(!color){ return null; }
color.rgb = color.slice(0, 3);
color.hex = color.rgbToHex();
+
return Object.append(color, this);
});
@@ -94,11 +92,8 @@ Color.implement({
invert: function(){
- return new Color(255-this[0],255-this[1],255-this[2]);
+ return new Color(255-this[0], 255-this[1], 255-this[2]);
- /*return new Color(this.map(function(value){
- return 255 - value;
- }));*/
}
});
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/moo-extend/Element.Extend.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/moo-extend/Element.Extend.js b/jspwiki-war/src/main/scripts/moo-extend/Element.Extend.js
index e36316b..70161f1 100644
--- a/jspwiki-war/src/main/scripts/moo-extend/Element.Extend.js
+++ b/jspwiki-war/src/main/scripts/moo-extend/Element.Extend.js
@@ -358,7 +358,7 @@ Element.implement({
Array.from(this.options).each( function(option){
- if (option.defaultSelected){ values.push(option.value || option.text); }
+ if (option.defaultSelected){ values[values.length] = option.value || option.text; }
});
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/moo-extend/String.Extend.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/moo-extend/String.Extend.js b/jspwiki-war/src/main/scripts/moo-extend/String.Extend.js
index ed5ce1b..12f34db 100644
--- a/jspwiki-war/src/main/scripts/moo-extend/String.Extend.js
+++ b/jspwiki-war/src/main/scripts/moo-extend/String.Extend.js
@@ -57,6 +57,14 @@ String.implement({
return this.replace(/([a-z\xe0-\xfd])([A-Z\xc0-\xdd])/g,"$1 $2");
},
+ //ES6 polyfill
+ startsWith: function( match ){
+ return !this.indexOf(match);
+ },
+ endsWith: function( match ){
+ return this.slice( -match.length ) == match ;
+ },
+
/*
Function: trunc
Truncate a string to a maximum length
@@ -202,6 +210,9 @@ String.implement({
> "zebra".sliceArgs( "zebra-eee-ffa" ); //returns ['eee','ffa']
> "zebra".sliceArgs( "horse" ); //returns null
> "zebra".sliceArgs( "zebra" ); //returns []
+ > "zebra".sliceArgs( "horse zebra-eee-ffa" ); //returns ['eee','ffa']
+ > "zebra".sliceArgs( "zebra-eee-ffa monkey" ); //returns ['eee','ffa']
+ > "zebra".sliceArgs( "horse zebra-eee-ffa monkey" ); //returns ['eee','ffa']
*/
sliceArgs: function(element, regexp){
@@ -223,8 +234,8 @@ String.implement({
Return a (string) classname to invoke the contextual colors.
Example
- > 'panel'.fetchContext( 'accordion-danger') => 'panel panel-danger'
- > 'panel'.fetchContext( 'commentbox-success') => 'panel panel-success'
+ > "panel".fetchContext( "accordion-danger") => 'panel panel-danger'
+ > "panel".fetchContext( "commentbox-success") => 'panel panel-success'
*/
fetchContext : function(element){
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/moo-extend/Textarea.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/moo-extend/Textarea.js b/jspwiki-war/src/main/scripts/moo-extend/Textarea.js
index 49b465a..07b1b9c 100644
--- a/jspwiki-war/src/main/scripts/moo-extend/Textarea.js
+++ b/jspwiki-war/src/main/scripts/moo-extend/Textarea.js
@@ -78,6 +78,9 @@ var Textarea = new Class({
toElement: function(){
return this.ta;
},
+ focus: function(){
+ this.ta.focus();
+ },
/*
Function: getValue
@@ -86,6 +89,12 @@ var Textarea = new Class({
getValue: function(){
return this.ta.value;
},
+
+ setValue: function(value){
+ this.ta.value = value;
+ this.setSelectionRange(0,0);
+ return this;
+ },
/*
Function: slice
Invokes slice(..) on the value of the textarea
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Commands.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Commands.js b/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Commands.js
index 309aafb..42fba89 100644
--- a/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Commands.js
+++ b/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Commands.js
@@ -86,7 +86,6 @@ Snipe.Commands = new Class({
dialog,
dialogs = options.dialogs || {};
-
//add click buttons and dialogs
container.addEvent("click:relay([" + dataCmd + "])", function(event){
@@ -98,6 +97,7 @@ Snipe.Commands = new Class({
// input fields (eg checkboxes) keep the default behaviour; other click events are disabled
if( !this.match("input") ){ event.stop(); }
+
});
//see if there are any dialogs linked to a button. Eg: "div.dialog.<command>"
@@ -234,9 +234,17 @@ Snipe.Commands = new Class({
//console.log("Snipe.Commands: createDialog() " + command + " ",dialog );
- if( typeOf(dialog) != "array" ){ dialog = [ Dialog.Selection, { body: dialog } ]; }
+ if( typeOf(dialog) != "array" ){
+
+ dialog = [ Dialog.Selection, { body: dialog } ];
+
+ }
+
+ if( !dialog[1].relativeTo ){
+
+ dialog[1].relativeTo = this.options.relativeTo || document.body;
- if( !dialog[1].relativeTo ){ dialog[1].relativeTo = this.options.relativeTo || document.body; }
+ }
dialog[1].autoClose = false;
@@ -262,7 +270,6 @@ Snipe.Commands = new Class({
button = self.btns[command];
//console.log("Snipe.Commands: openDialog() " + command + " " + activeDlg);
-
if( activeDlg && (activeDlg != newDlg) ){ activeDlg.hide(); }
self.activeDlg = self.dlgs[command];
@@ -284,7 +291,6 @@ Snipe.Commands = new Class({
button = self.btns[command];
//console.log("Snipe.Commands: closeDialog() " + command )
-
if( self.dlgs[command] == self.activeDlg ){ self.activeDlg = null; }
if( button ){ button.removeClass("active"); }
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Sections.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Sections.js b/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Sections.js
index 7e2a4cb..940e483 100644
--- a/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Sections.js
+++ b/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Sections.js
@@ -18,19 +18,18 @@
/*eslint-env browser*/
/*global $, Class, Events, Snipe */
/*
-Class: SnipEditor.Sections
- This dialog displays the list of page sections.
+Class: Snipe.Sections
+ This class implement section based editing in Snipe.
+ Based on the selected section, the Snipe textarea will be filled with a
+ part of the full content of the main textarea.
+ At all times the main textarea will contain the full text.
- (all) - allows to select all sections (auto generated)
- start-of-page - only present when first section starts on an offset > 0
- section1..n - section titles, with indentation level depending on their weight
+ This class keeps track for the current list of page section titles.
- The set of sections is generated by the parseSections() callback handler.
- This parser returns an array of section "descriptors":
+ The set of sections is generated by the parser() callback handler.
+ That parser returns an array of section "descriptors":
> [ {title:text, start:char-offset, indent:indentation-level}, ... ]
- Clicking an entry triggers the updateSections() callback handler.
- FIXME: why not fire an onAction event (similar to other dialogs)
Depends:
Snipe
@@ -38,18 +37,19 @@ Depends:
Example:
(start code)
div.cage
- div.btn.btn-link
- span.icon-bookmark
- span.caret
- ul.dropdown-menu [data-sections="div"][data-hover-parent=".cage"]
- li a first
- li a ..
- li a.dropdown-divider
- li a ..
-
-
- new Snipe.Sections( sectionDropDown, {
- snipe: snipe,
+ div.sections
+ button.btn.btn-default
+ span.icon-bookmark
+ span.caret
+ ul.dropdown-menu[data-hover-parent="div"]
+ li a first
+ li a ..
+ li a.dropdown-divider
+ li a ..
+
+ new Snipe.Sections( snipe, {
+ main: <main textarea>
+ menu: <ul dropdownmenu>,
parser: function(text){ .. return [[{title, start, depth}],..]; }
});
(end)
@@ -61,31 +61,34 @@ Snipe.Sections = new Class({
Binds: ["show","update","action"],
options: {
- //snipe: snip-editor
+ //main
+ //menu
//parser: function(text){ returns [[title,start,depth]..] }
all: "( all )".localize(),
+ sections: ".sections",
startOfPage: "Start of Page".localize()
},
- initialize: function(element, options){
+ initialize: function(snipe, options){
- var self = this,
- snipe = options.snipe;
+ var self = this;
- self.container = element;
+ self.snipe = snipe;
+ self.main = options.main;
self.parser = options.parser;
- self.list = element.getElement("ul").addEvent("click:relay(a)", self.action);
+ if( options.menu ){
- self.main = snipe.get("mainarea");
- self.work = $( snipe.get("textarea") );
+ self.list = options.menu.addEvent("click:relay(a)", self.action);
- snipe.addEvent( "change", self.update.debounce(500) );
+ }
self.parse();
self.action( location.search ); //url?section=0..n
- self.show();
+ self.menu();
+ //finally, connect to the update event of snipe !
+ snipe.addEvent( "change", self.update );
},
/*
@@ -97,14 +100,14 @@ Snipe.Sections = new Class({
> 0 : start-of-page (if applicable) => title=s-1 => cursor=-1
> 1..n : page sections => title=s0..sn => cursor=0..n
*/
- parse: function(){
+ parse: function( ){
this.sections = this.parser( this.main.value );
},
/*
- Function: show
+ Function: menu
UPDATE/RFEFRESH the section dropdown-menu.
Highlight the current item.
@@ -124,97 +127,95 @@ Snipe.Sections = new Class({
a.indent-0.section99 Title-Section-2
(end)
*/
- show: function( ){
+ menu: function( ){
- //console.log("Sections show",this.current, this.sections.length, this.sections[3]);
+ //console.log("menu", this.current, this.sections.length, this.sections);
var data = [],
+ list = this.list,
options = this.options,
current = this.current,
sections = this.sections,
- addItem = function(indent,name,offset){
-
- data.push("li" + (offset==current ? ".active" : ""),[
- "a.indent-" + indent + ".section" + offset, { html:name }
+ addItem = function(item, index){
+ data.push("li" + (index == current ? ".active" : ""),[
+ "a.indent-" + item.depth + ".section" + index, { html:item.title }
]);
-
};
- addItem(0, options.all ,-2);
+ if( list ){
- if( sections[0] ){
+ addItem({ depth:0, title:options.all }, -2);
- if( sections[0].start > 0 ){ addItem(0, options.startOfPage, -1); }
+ if( sections[0] ){
- data.push( "li.divider" );
-
- sections.each( function(item, idx){
+ if( sections[0].start > 0 ){
+ addItem({ depth:0, title:options.startOfPage }, -1);
+ }
+ data.push( "li.divider" );
+ sections.each( addItem );
+ }
- addItem( item.depth, item.title/*.trunc(36)*/, idx );
+ list.empty().adopt( data.slick() );
- });
+ list.getParent().ifClass( current >= -1, "section-selected");
}
- this.list.empty().adopt( data.slick() );
-
},
/*
Function: update
- Make sure that changes to the work textarea are propagated to the main textarea.
- This function handles the propagation of changes into the main textarea.
+ This function handles the propagation of changes from snipe to the main textarea.
+ It is triggered by a change event on snipe.
*/
update: function(){
- //console.log("****Snipe.Sections : change main");
-
var self = this,
main = self.main,
- work = self.work.value,
+ work = self.snipe.get("value"),
s = main.value;
//insert \n to ensure the next section always starts on a new line.
if( work.slice(-1) != "\n" ){ work +="\n"; }
//console.log("change txta: from="+self.begin+ " end="+self.end);
- main.value = s.slice(0, self.begin) + work + s.slice(self.end);
+ if( work != s.slice(self.begin, self.end) ){
- self.end = self.begin + work.length;
+ main.value = s.slice(0, self.begin) + work + s.slice(self.end);
- self.parse();
- self.show();
+ self.end = self.begin + work.length;
+ self.parse();
+ }
+ self.menu(); //always update menu, independent of the content of main
},
/*
Function: action
- This function copies the selected section from the main to the work textarea.
- It is invoked at initialization and through the dialog onAction click handler.
+ This function copies the selected section from the main to the snipe textarea.
+ It is invoked at initialization and through click handlers in the
+ section dropdown menu.
Arguments:
- item - index of selected section: all, -1, 0..n
+ item - index of selected section: all(-2), -1, 0..n
*/
- action:function( item ){
+ action: function( item ){
- //console.log("Sections: action",item);
var self = this,
main = self.main.value,
- work = self.work,
sections = self.sections,
begin = 0,
end = main.length;
if( item ){
- //item.target => event.target; this is an onclick invocation
+ //item.target => event.target; this is an onclick invocation!
if( item.target ){ item = item.target.className; }
//section-2=All, section-1=StartOfPage, section0..section99=rest
item = ( item.match( /section=?(-?\d+)/ )||[,-2])[1].toInt();
-
if( item == -1 ){
//show the Start Of Page, prior to the first real section
@@ -223,7 +224,7 @@ Snipe.Sections = new Class({
} else if(item >= 0 && sections[item] ){
begin = sections[item].start;
- if( sections[item+1] ){ end = sections[item+1].start; }
+ if( sections[item + 1] ){ end = sections[item + 1].start; }
}
@@ -231,19 +232,12 @@ Snipe.Sections = new Class({
}
- //work.value = ""; //FIXME google chrome 43.0.2357.65 bug -- if omitted, the textarea is displayed EMPTY!! ??
- work.value = main.slice(begin, end);
- work.setSelectionRange(0,0); //why not go via Textarea()..., for better bw compat.
self.begin = begin;
self.end = end;
- //section-selected class : turn bookmark icon red or blue
- self.container.ifClass( item >= -1, "section-selected");
-
- //update the dropdown menu, and highlight the current item
- self.show();
-
- work.fireEvent("change"); //needed to rerun page preview
+ //finally set the new snipe value
+ //note: this triggers a change event, and calls update()
+ self.snipe.set("value", main.slice(begin, end) );
return false; //stop click event propagation
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Snips.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Snips.js b/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Snips.js
index 9ffade6..a8d3b8e 100644
--- a/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Snips.js
+++ b/jspwiki-war/src/main/scripts/wiki-edit/Snipe.Snips.js
@@ -76,22 +76,23 @@ Snipe.Snips = new Class({
if( typeOf(suggest) == "string" ){
snip.suggest = {
- pfx: RegExp( suggest + "$" ),
+ lback: RegExp( suggest + "$" ),
match: RegExp( "^" + suggest )
}
- //console.log( snip.suggest );
+
}
self.suggestions[cmd] = snip;
- } else {
-
- //otherwise regular snippet
+ //otherwise regular snippet
+ //} else {
}
//check for snip dialogs -- they have the same name as the command
- if( snip[cmd] ){ self.dialogs[cmd] = snip[cmd]; }
+ //TODO better: use the dialog property !
+ if( snip[cmd] ){ self.dialogs[cmd] = snip[cmd]; } //deprecated
+ if( snip.dialog ){ self.dialogs[cmd] = snip.dialog; }
snips[cmd] = snip;
@@ -110,7 +111,7 @@ Snipe.Snips = new Class({
for( cmd in this.snips ){
- if( fromStart.test( cmd + "$" ) ){ return cmd; }
+ if( fromStart.endsWith( cmd ) ){ return cmd; }
}
@@ -120,7 +121,7 @@ Snipe.Snips = new Class({
/*
Function: matchSuggest
- Lookup a cmd enter just in front of the caret/cursor of the workarea..
+ Lookup a cmd which matches the suggestion look-back and match reg-exps.
snip.suggest => {
start: (number) start position,
@@ -130,17 +131,12 @@ Snipe.Snips = new Class({
*/
matchSuggest: function(){
- var cmd, snip, pfx, match, result, suggest,
+ var cmd, snip, lback, match, result, suggest,
suggestions = this.suggestions,
workarea = this.workarea,
caret = workarea.getSelectionRange(),
fromStart = workarea.getFromStart();
- //"selectInline", "selectBlock", "selectStartOfLine";
-
- //var SOL = workarea.isCaretAtStartOfLine();
- //var EOL = workarea.isCaretAtEndOfLine();
-
for( cmd in suggestions ){
snip = suggestions[cmd];
@@ -149,23 +145,23 @@ Snipe.Snips = new Class({
suggest = snip.suggest;
- if( suggest.pfx ){
+ if( suggest.lback ){
- pfx = fromStart.match( suggest.pfx );
+ lback = fromStart.match( suggest.lback );
- if( pfx ){
+ if( lback ){
- console.log("SUGGEST Prefix ", cmd, suggest.pfx, pfx.getLast() );
- pfx = pfx.getLast(); //match last (x)
+ //console.log("SUGGEST Look-Back ", cmd, suggest.lback, lback.getLast() );
+ lback = lback.getLast(); //match last (x)
- match = workarea.slice( caret.start - pfx.length )
+ match = workarea.slice( caret.start - lback.length )
.match( suggest.match );
- console.log("SUGGEST Match ", suggest.match, match );
+ //console.log("SUGGEST Match ", suggest.match, match );
if( match ){
- result = { pfx: pfx, match: match.getLast() } ;
+ result = { lback: lback, match: match.getLast() } ;
}
@@ -251,9 +247,9 @@ Snipe.Snips = new Class({
for( pattern in patterns ){
pos = text.lastIndexOf( pattern );
+
if( (pos > -1) && (text.indexOf( patterns[pattern], pos ) == -1) ){
return inscope;
-
}
}
return !inscope;
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/19b54311/jspwiki-war/src/main/scripts/wiki-edit/Snipe.js
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/scripts/wiki-edit/Snipe.js b/jspwiki-war/src/main/scripts/wiki-edit/Snipe.js
index 2b090e8..19ddc5b 100644
--- a/jspwiki-war/src/main/scripts/wiki-edit/Snipe.js
+++ b/jspwiki-war/src/main/scripts/wiki-edit/Snipe.js
@@ -102,7 +102,7 @@ var Snipe = new Class({
sectionParser: function(){ return {}; }
},
- initialize: function(el, options){
+ initialize: function(element, options){
options = this.setOptions(options).options;
@@ -117,13 +117,15 @@ var Snipe = new Class({
The main textarea is hidden and contains always the complete document.
On submit, the mainarea is send back to the server.
*/
- main = self.mainarea = $(el),
- work = main.clone().erase("name").inject( main.hide(), "before" ),
- container = options.container || work.form,
+ //main = self.mainarea = $(el),
+ //work = main.clone().erase("name").inject( main.hide(), "before" ).addClass("snipe-work"),
+ container = options.container || $(element).form,
// Augment the textarea element with extra capabilities
// Make sure the content of the mainarea is always in sync with the workarea
- textarea = self.textarea = new Textarea( work );
+ //textarea = self.textarea = new Textarea( work );
+ textarea = self.textarea = new Textarea( element );
+
self.directsnips = new Snipe.Snips( textarea, options.directsnips );
self.snippets = new Snipe.Snips( textarea, options.snippets );
@@ -133,14 +135,14 @@ var Snipe = new Class({
//feed the find dialog with searchable content
get: function(){
var selection = textarea.getSelection();
- return (selection=="") ? work.value : selection;
+ return (selection=="") ? element.value : selection;
//return (selection=="") ? textarea.getValue() : selection;
},
set: function(v){
var s = textarea.getSelectionRange();
- //self.fireEvent("beforeChange");
+ self.fireEvent("beforeChange"); //make undoable
//textarea[ s.thin ? "setValue" : "setSelection" ](v);
- s.thin ? work.value = v : textarea.setSelection(v);
+ s.thin ? element.value = v : textarea.setSelection(v);
self.fireEvent("change");
}
}
@@ -150,8 +152,8 @@ var Snipe = new Class({
//Commands are entered via tab-completion, button clicks, or a dialog.
//Snipe.Commands ensures that at most one dialog is open at the same time.
self.commands = new Snipe.Commands( container, {
- //onOpen: function( /*command*/ ){ work.focus(); },
- onClose: function( /*command*/ ){ work.focus(); },
+ onOpen: function( /*command*/ ){ element.focus(); },
+ onClose: function( /*command*/ ){ element.focus(); },
onAction: self.action,
dialogs: self.snippets.dialogs,
relativeTo: textarea
@@ -160,7 +162,7 @@ var Snipe = new Class({
self.reset();
- work.addEvents({
+ element.addEvents({
keydown: self.keystroke,
keypress: self.keystroke,
@@ -171,7 +173,7 @@ var Snipe = new Class({
click: self.suggest.debounce(),
input: (function( ){
- console.log("***Snipe: dom textarea input :");
+ //console.log("change event on input");
self.fireEvent("change");
}).debounce()
@@ -193,7 +195,7 @@ var Snipe = new Class({
*/
toElement: function(){
- return $(this.textarea);
+ return this.textarea.toElement();
},
/*
@@ -205,7 +207,8 @@ var Snipe = new Class({
*/
get: function(item){
- return( /mainarea|textarea/.test(item) ? this[item] :
+ return( "value" == item ? this.textarea.getValue() :
+ /mainarea|textarea/.test(item) ? this[item] :
/snippets|directsnips|autosuggest|tabcompletion|smartpairs/.test(item) ? this.options[item] :
null );
@@ -214,6 +217,7 @@ var Snipe = new Class({
/*
Function: set
Set/Reset some of the options of the snip-editor.
+ Also use to set/reset the content of the textarea. (eg section editing)
Arguments:
item - snippets|directsnips|autosuggest|tabcompletion|smartpair
@@ -223,9 +227,18 @@ var Snipe = new Class({
*/
set: function(item, value){
- if( /snippets|directsnips|autosuggest|tabcompletion|smartpairs/.test(item) ){
+ if( item == "value" ){
+
+ this.textarea.setValue( value );
+ this.fireEvent("beforeChange"); //make undoable
+ this.textarea.focus();
+
+ } else if( /snippets|directsnips|autosuggest|tabcompletion|smartpairs/.test(item) ){
+
this.options[item] = value;
+
}
+
return this.fireEvent("change");
},
@@ -242,7 +255,7 @@ var Snipe = new Class({
*/
shortcut: function(e){
- var key, keycmd;
+ var key, cmd;
if( e.shift || e.control || e.meta || e.alt ){
@@ -252,14 +265,14 @@ var Snipe = new Class({
(e.alt ? "alt+":"") +
e.key,
- //console.log("shortcut ",key);
- keycmd = this.snippets.keys[key];
+ console.log("shortcut ",key);
+ cmd = this.snippets.keys[key];
- if ( keycmd ){
+ if ( cmd ){
- //console.log("Snipe shortcut",key,keycmd,e.code);
+ //console.log("Snipe shortcut", key, cmd, se.code);
e.stop();
- this.commands.action( keycmd );
+ this.commands.action( cmd );
}
}
@@ -310,11 +323,10 @@ var Snipe = new Class({
var self = this,
txta = self.textarea,
- //el = txta.toElement(),
key = e.key,
caret = txta.getSelectionRange();
- txta.toElement().focus();
+ txta.focus();
if( /up|down|esc/.test(key) ){
@@ -512,7 +524,6 @@ var Snipe = new Class({
Function: setContext
Store the active snip. (state)
EG, subsequent handling of dialogs.
- As long as a snippet is active, the textarea gets the css class {{.activeSnip}}.
Arguments:
snip - snippet object to make active
@@ -527,7 +538,6 @@ var Snipe = new Class({
//console.log("Snipe.setContext",snip,suggest);
this.context = { snip:snip, suggest:suggest };
- this.toElement().addClass("activeSnip");
},
@@ -538,9 +548,9 @@ var Snipe = new Class({
*/
reset: function(){
- //console.log("Snipe:reset", this.context);
- this.context = {};
- this.toElement().removeClass("activeSnip").focus();
+ console.log("Snipe:reset", this.context);
+ this.context = null;
+ this.textarea.focus();
this.commands.close();
},
@@ -618,11 +628,10 @@ var Snipe = new Class({
console.log( "Snipe.suggest ",suggest );
this.setContext( null/*snip*/, suggest );
- return this.commands.action( suggest.cmd , suggest.pfx );
+ return this.commands.action( suggest.cmd , suggest.lback );
}
-
- this.commands.close();
+ this.reset();
}
},
@@ -630,160 +639,222 @@ var Snipe = new Class({
/*
Function: action
This function executes the command action.
- It will insert the snippet and update the selection and caret.
+ It will coordinate to get the snippet inserted and move the
+ caret to the proper position after insertion.
- It looks up and processes the snippet.
- - insert the snippet text at the caret in the textarea.
- - when text was selected (prior to the click or keyup event):
- - the snippet text will replace the selection
- - the selection will be passed as a parameter into the snippet
- - if the snippet has ONE parameter, the snippet text will be toggled:
- i.e. remove the snippet when already present, otherwise insert the snippet
+ Actions can be triggered via:
+ - tab-completion
+ - click-event from the [data-cmd] DOM element
+ - short-cut key
+ - matched suggestion (with look-back and match strings)
Arguments:
cmd - (string) used to loopup the snippet
args - (optional) additional snippet arguments (eg value passed via a dialog)
*/
- action: function( cmd ){
+ action: function( cmd /*, more command arguments */ ){
var self = this,
args = Array.slice(arguments, 1),
snip = self.snippets.get( cmd ),
- //snippet = snip.snippet,
- s = snip.snippet,
- suggest = snip.suggest && self.context.suggest,
-
txta = self.textarea,
- caret = txta.getSelectionRange(),
- hasCaret = !caret.thin,
- caretStart = caret.start,
+ caret,
+ snipXL,
+ snippet = snip.suggest ? args.join() : snip.snippet,
+ suggest = snip.suggest && self.context && self.context.suggest;
+
+ function unesc(s){ return s.replace(/~\{/g, "{"); }
- pfx, sel, sfx, snipArr, selectionLength,
- /* match "pfx{selection}sfx" into ["pfx","selection","sfx"] */
- /* do not match "pfx~{do-not-match}sfx" */
- snipSelection = /(^|[\S\s]*[^~])\{([^\{\}]+)\}([\S\s]*)/,
- snipEscapeChar = /~\{/g;
+ console.log("Snipe:action ", cmd, "snippet=",snippet, "args=",args, "suggest=",suggest );
- function setCaret(start,end){ txta.setSelectionRange(start, end); }
- function removeEscapeChar(s){ return s.replace(snipEscapeChar, "{"); }
+ if( !snip ) return;
- console.log("Snipe:action ", snip, s, cmd, args,suggest );
+ if( snip.event ){
+ //console.log("Snipe:action Event: ",snip.event);
+ self.fireEvent(snip.event, arguments);
- if( snip ){
+ } else {
- if( snip.event ){
+ self.fireEvent("beforeChange"); //make action undoable
- //console.log("Snipe:action() fire-event: ",snip.event);
- return self.fireEvent(snip.event, arguments);
+ if( suggest ){
+
+ snippet = self.suggestAction( txta, snippet, suggest.lback, suggest.match);
}
- this.fireEvent("beforeChange"); //CHECKME
- //adjust caret based on suggestion context
- if( suggest ){
+ /*
+ Match "pfx{=copy-selection}sfx" and replace by "pfx<selection>sfx"
+ snippet = snippet.replace(/..../, function(match, target){
+ if(selection){
+ target = selection; selection = "";
+ }
+ return target; //alse removing the {= and }
+ });
+ */
- s = args.join(); //result of the suggest dialog
- selectionLength = suggest.match.length;
- if( s.startsWith(suggest.pfx) ){
+ /*
+ Match "pfx{selection}sfx"
- s = s.slice(suggest.pfx.length);
- selectionLength -= suggest.pfx.length;
+ snippet = snippet.replace( /regexp/, selection || RegExp.$1 );
- } else {
+ and also handle toggle !!?
+ */
- caretStart -= suggest.pfx.length;
- }
+ // match "pfx{selection}sfx" into ["pfx","selection","sfx"]
+ // do not match "pfx~{do-not-match}sfx"
+ if( snipXL = snippet.match( /(^|[\S\s]*[^~])\{([^!\{\}][^\{\}]*)\}([\S\s]*)/ ) ){
+ //if( snipXL = snippet.match( /(^|[\S\s]*[^~])\{([^\{\}]+)\}([\S\s]*)/ ) ){
+
+ //console.log("Snipe:action complex snippet 'pfx{selection}sfx' ", pfx, sel, sfx, caret.thin );
+ self.injectXL( txta,
+ snippet,
+ unesc( snipXL[1] ), //pfx
+ snipXL[2], //sel
+ unesc( snipXL[3] ) //sfx
+ );
- //move the caret according to suggest pfx and match
- setCaret( caretStart, caretStart + selectionLength );
- hasCaret = selectionLength > 0;
+ } else {
+
+ //if no selection, just insert and move caret after inserted snippet
+ caret = txta.getSelectionRange();
+ snippet = unesc(snippet);
+
+ //console.log("Snipe:action simple snippet", caret.thin, snippet );
+ self.inject( txta,
+ snippet,
+ caret.start + (caret.thin ? snippet.length : 0),
+ caret.thin ? 0 : snippet.length );
}
- if( (snipArr = s.match( snipSelection )) ){
+ }
- pfx = removeEscapeChar( snipArr[1] );
- sel = hasCaret ? txta.getSelection() : snipArr[2] ;
- sfx = removeEscapeChar( snipArr[3] );
+ self.reset();
+ self.fireEvent("change");
+ self.suggest.delay(1, self); //allow some time to finish any actions, before opening a new suggestion dialog
- console.log("found a 'pfx{selection}sfx' snippet", snipArr, pfx, sel, sfx,hasCaret );
+ },
- if( hasCaret ) {
+ /*
+ Function: suggestAction
+ Adjust the snippet and the caret based on the suggestion context.
+ The selection is set to the matched suggestion string, to prepare for the later
+ snippet replacement.
+ When the snippet starts with the look-back string; only the last part
+ of the matched suggestion string should be replaced by the snippet.
+ Returns a adjusted snippet.
+
+ Example: ($==caret position)
+ [te$st] => lback = "te", match = "test", snippet ="wiki-page"
+ Selection will become "test", and snippet will become "wiki-page"
+ [te$st] => lback = "te", match = "test", snippet ="team-page"
+ Selection will become "st", and snippet will become "am-page"
+ */
+ suggestAction: function( txta, snippet, lback, match){
- if( sel.startsWith(pfx) && sel.endsWith(sfx) ){
+ var start = txta.getSelectionRange().start,
+ len = match.length;
- console.log("TOGGLE: pfx/sfx matched inside the selection",caret.start,caret.end);
- sel = sel.slice( pfx.length, -sfx.length );
- pfx = sfx = "";
+ //console.log("Snipe:suggestAction ",snippet,lback,match );
+ if( snippet.startsWith( lback ) ){
- } else if( txta.getFromStart().endsWith(pfx)
- && txta.getTillEnd().startsWith(sfx) ){
+ //remove the look-back part of the snippet
+ snippet = snippet.slice( lback.length );
+ len -= lback.length;
- console.log("TOGGLE: pfx/sfx matched outside the selection",caret.start,caret.end);
- caretStart -= pfx.length;
- setCaret( caretStart, caret.end + sfx.length); //enlarge the selection
- pfx = sfx = "";
+ } else {
- }
- }
+ //move the cursor to the start of the match
+ start -= lback.length;
- s = pfx + sel + sfx;
- caretStart += pfx.length;
- selectionLength = sel.length;
+ }
- } else {
+ txta.setSelectionRange(start, start + len); //move the cursor
- console.log("plain text snippet", hasCaret,s );
- s = removeEscapeChar( s );
- caretStart += hasCaret ? 0 : s.length;
- selectionLength = hasCaret ? s.length : 0;
+ return snippet;
- }
+ },
- self.inject(s, caretStart, selectionLength);
- self.reset();
+ /*
+ Function: injectXL
+ Inject a complex snippet.
+ Complex snippet match this pattern: "pfx{selection}sfx".
+ The part inside the "{..}" should be replaced by the selection.
+ If the selection has already the pfx/sfx strings, they should be toggled.
+ Example
+ snippet: "__{bold}__", no selection
+ Snippet "__bold__" will be inserted, selection will become "bold"
+ snippet: "__{bold}__", selection:"pipo"
+ Snippet "__pipo__" will be inserted, selection will become "pipo"
+ snippet: "__{bold}__", selection:__"pipo"__
+ Snippet "pipo" will replace "__pipo__", selection will become "pipo"
+ snippet: "__{bold}__", selection:"__pipo__"
+ Snippet "pipo" will replace selection, selection will become "pipo"
+ */
+ injectXL: function( txta, snippet, pfx, sel, sfx){
+
+ var caret = txta.getSelectionRange(),
+ start = caret.start;
+
+ if( !caret.thin ) {
- self.fireEvent("change");
- //allow to finish the actions, before opening a new suggestion dialog
- self.suggest.delay(10, self);
+ sel = txta.getSelection();
+ if( sel.startsWith(pfx) && sel.endsWith(sfx) ){
+
+ //console.log("TOGGLE: pfx/sfx matched inside the selection",caret.start,caret.end);
+ sel = sel.slice( pfx.length, -sfx.length );
+ pfx = sfx = "";
+
+ } else if( txta.getFromStart().endsWith(pfx)
+ && txta.getTillEnd().startsWith(sfx) ){
+
+ //console.log("TOGGLE: pfx/sfx matched outside the selection",caret.start,caret.end);
+ start -= pfx.length;
+ txta.setSelectionRange(start , caret.end + sfx.length);
+ pfx = sfx = "";
+
+ }
}
+ this.inject( txta, pfx + sel + sfx, start + pfx.length, sel.length);
+
},
- inject: function( snippet, start, selectionLength ){
+ /*
+ Function: inject
+ Replace the selection by the snippet and set a new selection.
+ Collapse leading and trailing \n characters
+ Autoindent the (multi-line) snippet.
+ */
+ inject: function( txta, snippet, start, selectionLen ){
- var self = this,
- txta = self.textarea,
- fromStart = txta.getFromStart(),
+ var fromStart = txta.getFromStart(),
prevline = fromStart.split(/\r?\n/).pop(),
- indentation = prevline.match(/^\s+/);
-
- //console.log(snippet,start,selectionLength);
+ indent = prevline.match(/^\s+/);
- //process whitespace before and after the snippet
- //collapse \n of previous line if the snippet starts with \n
if( snippet.test(/^\n/) && ( fromStart.test( /(^|[\n\r]\s*)$/ ) ) ) {
- //console.log("remove leading \\n", snippet);
+ //console.log("collapse leading \\n", snippet);
snippet = snippet.slice( 1 );
start--;
}
- //collapse \n of the next line when the snippet ends with a \n
if( snippet.test(/\n$/) && ( txta.getTillEnd().test( /^\s*[\n\r]/ ) ) ) {
- //console.log("remove trailing \\n", snippet);
+ //console.log("collapse trailing \\n", snippet);
snippet = snippet.slice(0, -1);
+ start--;
}
- //finally auto-indent the snippets internal newlines \n
- if( indentation ){
- snippet = snippet.replace( /\n/g, "\n" + indentation[0] );
+ if( indent ){
+ //console.log("auto-indent internal newlines \n");
+ snippet = snippet.replace( /\n/g, "\n" + indent[0] );
}
txta.setSelection( snippet )
- .setSelectionRange( start, start + selectionLength );
+ .setSelectionRange( start, start + selectionLen );
},
@@ -801,7 +872,7 @@ var Snipe = new Class({
el = txta.toElement();
return {
- main: this.mainarea.value,
+ //main: this.mainarea.value,
value: el.get("value"),
cursor: txta.getSelectionRange(),
scrollTop: el.scrollTop,
@@ -823,7 +894,7 @@ var Snipe = new Class({
el = txta.toElement();
self.reset();
- self.mainarea.value = state.main;
+ //self.mainarea.value = state.main;
el.value = state.value;
el.scrollTop = state.scrollTop;
el.scrollLeft = state.scrollLeft;