ssire / axel Goto Github PK
View Code? Open in Web Editor NEWA Javascript library for XML Authoring
Home Page: http://ssire.github.io/axel/
A Javascript library for XML Authoring
Home Page: http://ssire.github.io/axel/
The option attribute with a value of set
or unset
makes a primitive editor optional and shows a checkbox next to it to select it. It also changes the serialization of the englobing label and primitive editor content:
<xt:use type="text" option="set" label="Tag">enter some tag</xt:use>
will be serialized as <Tag>enter some tag</Tag>
as long as the checkbox is not unchecked
<xt:use type="text" option="unset" label="Tag">enter some tag</xt:use>
will not be serialized (no output) as long as the user does not select the checkbox or changes the content.
The suggestion here is to allow a new edited
value:
<xt:use type="text" option="edited" label="Tag">enter some tag</xt:use>
The semantic of edited
would be similar to unset
except that there would be no checkbox displayed to make the user interface simpler. Consequently the label / content would be serialized only if the content has been edited and changed to something different from the default content.
The class axel-option-unset
would be put on the handle as long as it contains the default data.
The following code in repeat.js :
if ($axel.binding) {
$axel.binding.install(this.curDoc, index[0], index[1]);
}
if ($axel.command) {
$axel.command.install(this.curDoc, index[0], index[1]);
}
does not install bindings or commands on 1st level child elements of an xt:repeat
Consequently if you need to do that you should better have a neutral div element as 1st and unique child of the xt:repeat.
Define a place for thoses messages and an API to store / retrieve messages.
We could use a $axel.region module for that with something like $axel.region.register( 'fr', { 'plugin:name' : { messages } } )
to register blocks of messages for a given plugin (using 'filter:name' for filters).
To switch language we could use a global setting such as $axel.setup( { region : 'fr' } )
to set current language ?
The video
plugin currently handles only YouTube video links (i.e. url's such as http://www.youtube.com/watch?v=qx3bIn5z2Ng).
That would nice if the plugin could also deals with DailyMotion video links (e.g. http://www.dailymotion.com/video/xu3pd_fischer-vs-spassky_sport).
Currently the getUniqueKey() returns a unique key that starts (per-construction) with the plugin type name, so it is basically possible to test for a given type such as in :
$axel(...).get(0).getUniqueKey().indexOf('someType') === 0
For future evolutions that would be better to introduce a specific function such as getPluginName (other names are possible such as getPluginType or getPluginClassname)
This would allow to not serialize content when use hasn't changed the default selection, or there is no default selection and the user didn't select anything.
Note: check how to have this interfer with a placeholder plugin parameter, i.e. what to do if there is a placeholder and if it is configured to be serialized (preserved) ?
This happens with repetition with a minOccurs of 0, when there was some slices set and the new content unsets it, the first slice is unchecked by the content of its fields is not reset to their default values.
This is a feature request to create an extension to AXEL to load / save some data in JSON format instead of XML. This requires to design first a bi-directional mapping between JSON and XML and second to write some alternative DOMDataSource and DOMLogger classes.
Potential starting points:
That would be usesful to anchor a class attribute on the img handle in the XTiger template, to use same CSS rule for the XTiger template and for the HTML static view.
Note: this is already supported in the 'text' plugin.
The editor that comes with AXEL define several Save buttons but they do not work when the application is launched from behind a WebDAV server. We should support it and makes clearer what the different Save buttons are for.
Currently the top-righ Save is only working on Firefox and the Save button in Preferences only work when the application is launched from scripts/server/server.rb
It does not serialize the attribute with an empty string in case the user does not edit the field, see also Issue #37
I have been using a idiom for repeated elements like
<xt:repeat minOccurs="0" maxOccurs="*" pseudoLabel="Aim">
<xt:use types="Aim" label="Aim"/>
</xt:repeat>
and within Aim we have
<xt:component name="Aim">
<div class="editElement title"><xt:use types="text" label="title"> title</xt:use> </div>
<xt:use types="text" label="description"> description</xt:use>
<xt:repeat minOccurs="0" maxOccurs="*" pseudoLabel="Goal" >
<xt:use types="Goal" label="Goal" />
</xt:repeat></div>
</xt:component>
which is what I mean by nested pseudoLabel elements. Anyway, $axel().xml() works fine,as does all the editing, but $axel.load() ignores the repeats beyond the first level (in this case, Aims repeat, but goal elements are not read). xt:repeat label="Goal" works, but of course, that is a different xml schema. I would try a different loader, but I did not figure out how to control which loader $axel.load uses.
window.getSelection is not the iframe window
Replacing it with the iframe window should make cursor positioning work in AXEL default demonstration editor (iframe one)
Create a 'photodrop' plugin to upload photo using Drag&Drop
The plugin could be based on this prototype : https://github.com/gsechaud/UploadingPhotoPlugin
The image content could be inlined directly within an XML element using a base64 string, this way there would be no need for a specific Ajax protocol. Of course the content should be serialized with a specific value (e.g. 'NOCHANGE') if it hasn't been changed, to avoid consuming too much bandwidth
Synopsis:
<xt:use types="hidden" label="nav">
<button id="first" accesskey="h" title="first slide"> « </button>
<button id="last" accesskey="l" title="last slide"> » </button>
</xt:use>
would be serialized as:
<nav>
<button id="first" accesskey="h" title="first slide"> « </button>
<button id="last" accesskey="l" title="last slide"> » </button>
</nav>
Some templates use the following trick to declare an hidden attribute which is set at template generation time, for instance to store a lang
attribute:
<span class="noshow">
<xt:attribute types="text" name="lang" values="en fr" default="en"/>
</span>
It is not clear how the general case could also covert that specific case. Maybe a simpler solution base on a filter would be sufficient, such as:
<xt:attribute types="text" name="lang" values="en fr" default="en" param="filter=hidden"/>
Currently these functions apply only to the first node containing a transformed template. Could be interested to also work with forrest.
Function xml() could accept a configuration object such as :
{ RootTag : 'name' }
if present it would become the document root element, otherwise serialization would give a forrest (contained in a string as usual).
As stated in the title. The generator method could be replaced with an onGenerate life cycle method that would be called first before onInit and that should return the handle as usual.
The main benefit will be to be able to create plugin filters that can change the plugin's generated markup.
Nota that this is an internal change that should not affect existing XTiger XML templates. However it affects all plugins written so far, so that they should be updated all at once.
Extend the demonstration template editor to allow viewing the current template source code with syntax highlighting, or even to edit the template using ACE editor, with future option to include a live syntax checker for XTiger.
The goal is to write template to directly using microformated HTML as target content model. In that case the class
attribute will be used to differentiate two components.
For instance to generate:
<div class="slide">
We could actually write:
<xt:component name="t_slide">
<span style="display: none"><xt:attribute name="class" types="text">slide</xt:attribute></span>
...
</xt:component>
<xt:use types="t_slide" label="div">
The suggestion is to support a new syntax for the label
:
<xt:use types="t_slide" label="div(slide)">
that would directly generate a <div class="slide">
in the target content model, without the need for the invisible span/attribute.
The main advantage is that it will allow to generate some elements that differ only by their class
attribute and that represent different XTiger components, which is not possible today.
For instance one will be able to write:
<xt:use types="t_header" label="div(header)">
<xt:use types="t_slide" label="div(slide)">
to generate:
<div class="header">...
<div class="slide">....
Where t_header
is declared by an xt:component
different than the t_slide
one.
It would be also possible to use that syntax in case of multi-choices with renaming, such as:
<xt:use types="t_header t_slide t_footer" label="div(header) div(slide) div(footer)"/>
My impression is that it is quite easy to implement into the the transformer, serializer and XML loader components.
Currently the link editor generates linkRef / linkText elements.
<xt:use types="link" label="Link"><a href="http://">title</a></xt:use>
Will generate output such as:
<Link>
<linkRef>http://groups.google.com/group/axel-dev/web/beyond-html-5-semantic-markup-css-editable-with-axel</linkRef>
<linkText>Beyond HTML 5 = semantic markup + CSS </linkText>
</Link>
Whereas:
<xt:use types="text" param="filter=wiki">enter some text</xt:use>
Will generate output such as:
<Link>
<LinkText>Today</LinkText>
<LinkRef>http://www.media.com</LinkRef>
</Link>
We should either allow to parameterize the output vocabulary (linkRef / LinkRef) or make it uniform.
This is a sub-problem of the general problem of parameterizing output vocabulary of primitive editors that generate more than a textual element but also some XML elements and/or attributes, which are then not defined through AXEL/XTiger label
or name
attributes.
For instance we could prefer to directly serialize links as <a href="...">...</a>
elements.
Currently it is possible to use prefixed names in attributes in the XML output model. That would be very useful to be able to use it on elements too, for instance to support editing of RDF documents. See also Issue #37
When editing a field which still contains the default value, we should just start editing with an empty input or textarea field, instead of leaving the default value (even if we select it all so that the first keystroke will replace it).
<xt:use types="checkbox" label="Reference" value="one" >one label</xt:use><br/>
<xt:use types="checkbox" label="Reference" value="two" >two label</xt:use><br/>
<xt:use types="checkbox" label="Reference" value="three">three label</xt:use>
Generates following HTML code :
<input id="one" type="checkbox"><label for="one">one label</label><br/>
<input id="two" type="checkbox"><label for="two">two label</label><br/>
<input id="three" type="checkbox"><label for="three">three label</label>
If only "one" and "three" checkboxes are checked, then it serializes as :
<Reference>one</Reference>
<Reference>three</Reference>
This requires an extension to DOMDataSource, a function hasDataForWithValue that would be like hasDataFor, but that would also check the value of the data is equal to the given value
When loading data, the 'checkbox' plugin load method would use hasDataForWithValue in the scope of the current point (a vector of siblings) and consume the matches (we may or may not search for a match only in 1st position or in other positions too, depending on robustness considerations)
The xmlloader algorithm and domdatasource need to be fixed, see also Issue #37
I encountered a case when using the editor and the input window, pasting some XML content with &
The & entity is replaced by its character in the input window (&) which is then fed as is to the XML parser that raises an error. Unfortunately DOMDataSource believe it is handing a normal XML document whereas it is a document instead (at least on FF).
Such situations should signal the error to the user.
Would be useful to create documents with embedded images serialized as text (data: base64 encoded string).
In addition, when this option is activated, the plugin could use a local representation of the image. This would allow to use image "upload" in demonstrations w/o the need to save images on a server, and even to generate a result document with embedded images.
Exemple de code pour générer l'image depuis une image URL :
function convertImgToBase64(url, callback, outputFormat){
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var img = new Image;
img.crossOrigin = 'Anonymous';
img.onload = function(){
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img,0,0);
var dataURL = canvas.toDataURL(outputFormat || 'image/jpeg');
callback.call(this, dataURL);
// Clean up
canvas = null;
};
img.src = url;
}
function doIt () {
window.console.log('Starting...')
convertImgToBase64('image url', function(base64Img){
var img = document.getElementById('output');
img.src = base64Img;
});
}
HTML5 load save APIs are making progresses, especially on Chrome
In some production code I use, I use to call finishTransmission from the target iframe created by the photo plugin with :
window.parent.finishTransmission(1,'images/15.jpeg')
as returned per the server in a HTML document just containing that script.
However this response is not executed if the photo upload dialog box has been dismissed by the user
I've reproduced the problem both on IE (which fires an error) and FF (that says nothing), not tested on other browsers.
I guess the reason could be that when the target iframe parent display style is set to none when the photo plugin is not visible, it's window has no parent or something like that.
One solution could be to install the iframe directly inside the body of the transformed template host document and leave it there whatever is the state of the photo plugin (visible or not).
Fixed with commit c8690da
The script only seems to work on Firefox (*), fix it for any browser as it improves self-description level of the template.
(*) got an error like "TypeError: Cannot read property 'length' of undefined"
Curently repeat.js uses can() execute() to "dispatch" a 'duplicate' and a 'remove' pseudo events (i.e. a method call on a plugin, or on a plugin enriched by a filter).
Replace them with true event synthesis in conjunction with the presence of the 'event' filter on the primitive editor. Complete event synthesis to cover all events described in https://github.com/ssire/axel/wiki/The-%27event%27-filter
Benefits:
Inconvenient:
Using straight "double-quoted" input causes incorrect XML to be serialized.
Example: <Series Label=""test"">
We should check if this character is allowed in XML attributes, and eventually replace it with a character entity in this situation (i.e. the entry field is an xt:attribute).
The 'text' plugin define a getDefaultData() to retrieve the default field value as per the template, however the 'select' does not. Instead it defines a this.defaultScreenData parameter. Maybe this functionality would deserve a common API, for instance to write filters common to several plugins. In that case we should take into account the fact that some 'plugins' such as 'select' may have multiple representation(s) and default value(s) for their representation in the UI and in the XML target model.
It seems AXEL is broken in recent IE versions (>= 9) ? The reason seems to be IE now supports DOM createTreeWalker method, which breaks AXEL TreeWalker sniffing.
Fixed with commit 83a9b3f
When placeholder is set to clear
the field is serialized as empty string, check that if the 'optional' filter is set the output XML element is also cancelled.
When placeholder attribute is set maybe the handle should hold an 'axel-placeholde' class to be able to style it (italics) ? Do not forget to remove that class if the field is loaded with something different than the placeholder.
Finally maybe 'placeholder' is not the best possible name, since contrary to HTML5 placeholder is not the message to display but an indication to treat the default content of the field as a placeholder. Other suggestion default=data|placeholder|data+placeholder
(data+placeholder to display default data as a placeholder but to consider it as data to be serialized even if unchanged)
Extend the wiki
filter to support a wiki_output=html
parameter that would serialize edited content as HTML (i.e. <span>, <a href>, <strong>, <em>
) instead of the current specific markup (i.e. <Fragment>, <Link>, @FragmentKind='important', @FragmentKind='verbatim'
).
Synopsis:
<xt:use types="text" param="filter=wiki;wiki_output=html">Type in **some text**</xtuse>
Accepts a plugin generator function that returns a string to be be instantiated with innerHTML. The handle will be identified with the 'axel-core-editable' class name that is normally set in onAwake function when using a classical generator.
Note that this is only possible with plugins that do not manage the 'handle' attribute
For instance http://ssire.github.com/axel/editor/editor.xhtml#templates/samples/Article.xhtml would open the Article template.
That would give the ability to send / publish links to template demonstations...
When the axel-add
and axel-remove
events are generated, add a event.cut
and event.paste
properties to tell if the slice was cut or pasted by the user.
This will ease up the development of callbacks that do initializations that must only be done once.
Currently AXEL serialization of characters replaces the & ampersand with its XML named entity &. This is done by encodeEntites in defaultbrowser.js :
if (s.indexOf('&') != -1) {
res = res.replace(/&(?![a-zA-Z]{3,5};)/g, '&'); // Avoid double encoding
}
However it avoids to convert it for named entities between 3 and 5 characters. The reasons are obscure, and why is it limited to entities between 3 and 5 characters ? Shouldn't it be limited only to XML named entities (amp, lt, gt, apos, quot) ?
For instance " is serialized as " which becomes " when loaded back into the editor which is serialized to " the second time !
At the same time &foobar; is serialized as &foobar; which is read as &foobar; and serialized back as &foobar;
Introduce a way to identify AXEL running version and eventually revision (or built) identifier.
We can expose them as new variables such as xtiger.version
and xtiger.revision
I am not sure how to create the revision string ? One difficulty is that currently the built lib (axel.js) is committed to the repository, hence we cannot set the revision to the commit ID since it will not be known before commiting the file...
I see those solutions:
ant build.lib
immediately after checkout)ant build.lib
to build the lib with a revision date set to the date of the last commit (obtained with git log -1
for instance) and ant build.lib.today
to force the revision date to be the date of the day and to be used only when building before committingMake a template to directly edit the XTiger XML spec. The template should output a HTML5 document directly viewable. For that purpose:
markup
, attribute
, sample
in the doc can be replaced with a simlpe tt
as per wiki filter with wiki_lang=html
<dfn id="truc">Truc</dfn>
) with referencing for instance [Some new term][id]
to create a definition and [id]
to create reference (using an internal dictionary to automatically update text when changing the definition)<cite>
to bibliographical references[1]
<xt:use handle="pre" types="text" label="pre"
param="shape=parent;type=textarea;layout=placed;enablelinebreak=true;filter=wiki;wiki_lang=html">Source</xt:use>
The template should allow writing specs such as that one
Actually xtdom.addClassName, xtdom.removeClassName and xtdom.replaceClassNameBy use a weak test to detect the class name :
(node.className.search(name) == -1)
the test gives false positive with names that contains the searched term, we must test for an exact match
When placing a xt:use with a choice between several components it generates a menu based on an HTML element. This menu can itself be placed in a dynamical container controlled with a :hover CSS rule. However that does not work on IE : each time the user starts mousing over the options of the select menu, the :hover pseudo-selector is invalidated and the dynamical container and the select menu disappear ! I do not see any obvious solution (apart not using dynamical menus on IE !), some candidate solutions include: using our own popudevice for the choice editor (choice.js) instead of the select menu adapting the existing choice editor (choice.js) so that select sets a 'over' class on all its ancestors when it is under the mouse (only for IE to limit overhead) what else ? Fixed with commit https://github.com/ssire/axel/commit/3427787af7754912398a9b1152947fef4bfa142a
To run auto-test from local file system on Firefox it is also necessary to set security.fileuri.strict_origin_policy to false in Firefox about:config panel. The FAQ should say so. This is similar to the instructions given in editor/editor.xhtml startup screen.
Currently it says: Exception while loading "Repeat.xhtml" : Access to restricted URI denied in Inspect button.
Allow server to return a warning to print in photo upload dialog box, warnings such as "your image could not be resized because of format (color space, etc.), you should better try with another image to improve performances" (I had the pb with CYMK images with eXist/Image module).
This is a request feature to create a "date" plugin for AXEL to edit a date with a standard calendar view. This is elaborated in the DatePicker wiki page.
Candidates :
Enable editing to quickly allow testing XTiger XML template authoring directly from within the editor
See https://developer.mozilla.org/en-US/docs/Bypassing_Security_Restrictions_and_Signing_Code
or https://support.mozilla.org/fr/questions/936845
Obviously this will break the demonstration editor facility to browse/load templates using a file dialog.
We should investigate how to rewrite the xtiger.util.fileDialog function in src/core/utils.js to use HTML5 FileAPI instead (http://dev.w3.org/2006/webapi/FileAPI/)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.