Skip to content

Commit

Permalink
Merge pull request #169 from Voog/format_inline_rewrite
Browse files Browse the repository at this point in the history
formatInline rewrite
  • Loading branch information
Oliver Pulges committed Jun 2, 2015
2 parents c8cb3d5 + 786433e commit 34164ca
Show file tree
Hide file tree
Showing 34 changed files with 4,269 additions and 1,489 deletions.
1,658 changes: 1,235 additions & 423 deletions dist/wysihtml-toolbar.js

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions dist/wysihtml-toolbar.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/wysihtml-toolbar.min.map

Large diffs are not rendered by default.

1,658 changes: 1,235 additions & 423 deletions dist/wysihtml.js

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions dist/wysihtml.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/wysihtml.min.map

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions examples/simple.html
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,11 @@ <h1>wysihtml5 - Simple Editor Example</h1>
<h2>Events:</h2>
<div id="log"></div>

<small>powered by <a href="https://github.com/xing/wysihtml5" target="_blank">wysihtml5</a>.</small>
<small>powered by <a href="https://github.com/voog/wysihtml" target="_blank">wysihtml</a>.</small>

<script src="../parser_rules/simple.js"></script>
<script src="../dist/wysihtml-toolbar.min.js"></script>
<script src="../parser_rules/simple.js"></script>

<script>
var editor = new wysihtml5.Editor("textarea", {
toolbar: "toolbar",
Expand Down Expand Up @@ -122,4 +123,4 @@ <h2>Events:</h2>
.on("redo:composer", function() {
log.innerHTML += "<div>redo:composer</div>";
});
</script>
</script>
8 changes: 4 additions & 4 deletions examples/wotoolbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,13 @@ <h1>wysihtml5 - Advanced Editor Example</h1>
<h2>Events:</h2>
<div id="log"></div>

<small>powered by <a href="https://github.com/xing/wysihtml5" target="_blank">wysihtml5</a>.</small>
<small>powered by <a href="https://github.com/voog/wysihtml" target="_blank">wysihtml</a>.</small>

<script src="jquery.1.10.2.js" type="text/javascript" charset="utf-8"></script>


<script src="../dist/wysihtml.min.js"></script>
<script src="../parser_rules/advanced_unwrap.js"></script>
<script src="../dist/wysihtml5x.min.js"></script>

<script>


Expand Down Expand Up @@ -512,4 +512,4 @@ <h2>Events:</h2>
}
});

</script>
</script>
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "wysihtml",
"version": "0.5.0-beta8",
"version": "0.5.0-beta9",
"devDependencies": {
"grunt": "~0.4.4",
"grunt-contrib-concat": "~0.4.0",
Expand All @@ -9,13 +9,13 @@
"grunt-contrib-uglify": "~0.3.0",
"happen": "^0.1.3",
"qunitjs": "1.15.0",
"qunit-assert-html": "^0.2.3",
"qunit-assert-html": "^0.3.2",
"grunt-open": "^0.2.3"
},
"dependencies": {
"rangy": "^1.3.0-alpha.20140921"
"rangy": "1.3.0"
},
"description": "h1. wysihtml 0.5.0-beta8",
"description": "h1. wysihtml 0.5.0-beta9",
"main": "Gruntfile.js",
"directories": {
"example": "examples",
Expand Down
10 changes: 10 additions & 0 deletions src/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ wysihtml5.Commands = Base.extend(
return result;
},

remove: function(command, commandValue) {
var obj = wysihtml5.commands[command],
args = wysihtml5.lang.array(arguments).get(),
method = obj && obj.remove;
if (method) {
args.unshift(this.composer);
return method.apply(obj, args);
}
},

/**
* Check whether the current command is active
* If the caret is within a bold text, then calling this with command "bold" should return true
Expand Down
30 changes: 20 additions & 10 deletions src/commands/bgColorStyle.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
/* In case background adjustment to any color defined by user is preferred, we cannot use classes and must use inline styles. */
/**
* Sets text background color by inline styles
*/
(function(wysihtml5) {
var REG_EXP = /(\s|^)background-color\s*:\s*[^;\s]+;?/gi;

wysihtml5.commands.bgColorStyle = {
exec: function(composer, command, color) {
var colorVals = wysihtml5.quirks.styleParser.parseColor((typeof(color) == "object") ? "background-color:" + color.color : "background-color:" + color, "background-color"),
var colorVals = wysihtml5.quirks.styleParser.parseColor("background-color:" + (color.color || color), "background-color"),
colString;

if (colorVals) {
colString = "background-color: rgb(" + colorVals[0] + ',' + colorVals[1] + ',' + colorVals[2] + ');';
if (colorVals[3] !== 1) {
colString += "background-color: rgba(" + colorVals[0] + ',' + colorVals[1] + ',' + colorVals[2] + ',' + colorVals[3] + ');';
}
wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", false, false, colString, REG_EXP);
colString = (colorVals[3] === 1 ? "rgb(" + [colorVals[0], colorVals[1], colorVals[2]].join(', ') : "rgba(" + colorVals.join(', ')) + ')';
wysihtml5.commands.formatInline.exec(composer, command, {styleProperty: 'backgroundColor', styleValue: colString});
}
},

state: function(composer, command) {
return wysihtml5.commands.formatInline.state(composer, command, "span", false, false, "background-color", REG_EXP);
state: function(composer, command, color) {
var colorVals = color ? wysihtml5.quirks.styleParser.parseColor("background-color:" + (color.color || color), "background-color") : null,
colString;


if (colorVals) {
colString = (colorVals[3] === 1 ? "rgb(" + [colorVals[0], colorVals[1], colorVals[2]].join(', ') : "rgba(" + colorVals.join(', ')) + ')';
}

return wysihtml5.commands.formatInline.state(composer, command, {styleProperty: 'backgroundColor', styleValue: colString});
},

remove: function(composer, command) {
return wysihtml5.commands.formatInline.remove(composer, command, {styleProperty: 'backgroundColor'});
},

stateValue: function(composer, command, props) {
Expand Down
18 changes: 10 additions & 8 deletions src/commands/bold.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
(function(wysihtml5){
(function(wysihtml5) {

var nodeOptions = {
nodeName: "B",
toggle: true
};

wysihtml5.commands.bold = {
exec: function(composer, command) {
wysihtml5.commands.formatInline.execWithToggle(composer, command, "b");
wysihtml5.commands.formatInline.exec(composer, command, nodeOptions);
},

state: function(composer, command) {
// element.ownerDocument.queryCommandState("bold") results:
// firefox: only <b>
// chrome: <b>, <strong>, <h1>, <h2>, ...
// ie: <b>, <strong>
// opera: <b>, <strong>
return wysihtml5.commands.formatInline.state(composer, command, "b");
return wysihtml5.commands.formatInline.state(composer, command, nodeOptions);
}
};

}(wysihtml5));
116 changes: 16 additions & 100 deletions src/commands/createLink.js
Original file line number Diff line number Diff line change
@@ -1,114 +1,30 @@
(function(wysihtml5) {
var undef,
NODE_NAME = "A",
dom = wysihtml5.dom;

function _format(composer, attributes) {
var doc = composer.doc,
tempClass = "_wysihtml5-temp-" + (+new Date()),
tempClassRegExp = /non-matching-class/g,
i = 0,
length,
anchors,
anchor,
hasElementChild,
isEmpty,
elementToSetCaretAfter,
textContent,
whiteSpace,
j;
wysihtml5.commands.formatInline.exec(composer, undef, NODE_NAME, tempClass, tempClassRegExp, undef, undef, true, true);
anchors = doc.querySelectorAll(NODE_NAME + "." + tempClass);
length = anchors.length;
for (; i<length; i++) {
anchor = anchors[i];
anchor.removeAttribute("class");
for (j in attributes) {
// Do not set attribute "text" as it is meant for setting string value if created link has no textual data
if (j !== "text") {
anchor.setAttribute(j, attributes[j]);
}
}
}

elementToSetCaretAfter = anchor;
if (length === 1) {
textContent = dom.getTextContent(anchor);
hasElementChild = !!anchor.querySelector("*");
isEmpty = textContent === "" || textContent === wysihtml5.INVISIBLE_SPACE;
if (!hasElementChild && isEmpty) {
dom.setTextContent(anchor, attributes.text || anchor.href);
whiteSpace = doc.createTextNode(" ");
composer.selection.setAfter(anchor);
dom.insert(whiteSpace).after(anchor);
elementToSetCaretAfter = whiteSpace;
}
}
composer.selection.setAfter(elementToSetCaretAfter);
}

// Changes attributes of links
function _changeLinks(composer, anchors, attributes) {
var oldAttrs;
for (var a = anchors.length; a--;) {

// Remove all old attributes
oldAttrs = anchors[a].attributes;
for (var oa = oldAttrs.length; oa--;) {
anchors[a].removeAttribute(oldAttrs.item(oa).name);
}

// Set new attributes
for (var j in attributes) {
if (attributes.hasOwnProperty(j)) {
anchors[a].setAttribute(j, attributes[j]);
}
}
var nodeOptions = {
nodeName: "A",
toggle: false
};

}
function getOptions(value) {
var options = typeof value === 'object' ? value : {'href': value};
return wysihtml5.lang.object({}).merge(nodeOptions).merge({'attribute': value}).get();
}

wysihtml5.commands.createLink = {
/**
* TODO: Use HTMLApplier or formatInline here
*
* Turns selection into a link
* If selection is already a link, it just changes the attributes
*
* @example
* // either ...
* wysihtml5.commands.createLink.exec(composer, "createLink", "http://www.google.de");
* // ... or ...
* wysihtml5.commands.createLink.exec(composer, "createLink", { href: "http://www.google.de", target: "_blank" });
*/
wysihtml5.commands.createLink = {
exec: function(composer, command, value) {
var anchors = this.state(composer, command);
if (anchors) {
// remove <a> tag if there's no attributes provided.
if ((!value || !value.href) && anchors.length !== null && anchors.length !== undefined && anchors.length > 0)
{
for(var i=0; i < anchors.length; i++)
{
wysihtml5.dom.unwrap(anchors[i]);
}
return;
}
var opts = getOptions(value);

// Selection contains links then change attributes of these links
composer.selection.executeAndRestore(function() {
_changeLinks(composer, anchors, value);
});
} else {
// Create links
if (value && value.href) {
value = typeof(value) === "object" ? value : { href: value };
_format(composer, value);
}
if (composer.selection.isCollapsed() && !this.state(composer, command)) {
var textNode = composer.doc.createTextNode(opts.attribute.href);
composer.selection.insertNode(textNode);
composer.selection.selectNode(textNode);
}
wysihtml5.commands.formatInline.exec(composer, command, opts);
},

state: function(composer, command) {
return wysihtml5.commands.formatInline.state(composer, command, "a");
return wysihtml5.commands.formatInline.state(composer, command, nodeOptions);
}
};

})(wysihtml5);
8 changes: 3 additions & 5 deletions src/commands/fontSize.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
/**
* document.execCommand("fontSize") will create either inline styles (firefox, chrome) or use font tags
* which we don't want
* Instead we set a css class
* Set font size css class
*/
(function(wysihtml5) {
var REG_EXP = /wysiwyg-font-size-[0-9a-z\-]+/g;

wysihtml5.commands.fontSize = {
exec: function(composer, command, size) {
wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", "wysiwyg-font-size-" + size, REG_EXP);
wysihtml5.commands.formatInline.exec(composer, command, {className: "wysiwyg-font-size-" + size, classRegExp: REG_EXP, toggle: true});
},

state: function(composer, command, size) {
return wysihtml5.commands.formatInline.state(composer, command, "span", "wysiwyg-font-size-" + size, REG_EXP);
return wysihtml5.commands.formatInline.state(composer, command, {className: "wysiwyg-font-size-" + size});
}
};
})(wysihtml5);
15 changes: 10 additions & 5 deletions src/commands/fontSizeStyle.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
/* In case font size adjustment to any number defined by user is preferred, we cannot use classes and must use inline styles. */
/**
* Set font size by inline style
*/
(function(wysihtml5) {
var REG_EXP = /(\s|^)font-size\s*:\s*[^;\s]+;?/gi;

wysihtml5.commands.fontSizeStyle = {
exec: function(composer, command, size) {
size = (typeof(size) == "object") ? size.size : size;
size = size.size || size;
if (!(/^\s*$/).test(size)) {
wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", false, false, "font-size:" + size, REG_EXP);
wysihtml5.commands.formatInline.exec(composer, command, {styleProperty: "fontSize", styleValue: size, toggle: true});
}
},

state: function(composer, command, size) {
return wysihtml5.commands.formatInline.state(composer, command, "span", false, false, "font-size", REG_EXP);
return wysihtml5.commands.formatInline.state(composer, command, {styleProperty: "fontSize", styleValue: size});
},

remove: function(composer, command) {
return wysihtml5.commands.formatInline.remove(composer, command, {styleProperty: "fontSize"});
},

stateValue: function(composer, command) {
Expand Down
8 changes: 3 additions & 5 deletions src/commands/foreColor.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
/**
* document.execCommand("foreColor") will create either inline styles (firefox, chrome) or use font tags
* which we don't want
* Instead we set a css class
* Set color css class
*/
(function(wysihtml5) {
var REG_EXP = /wysiwyg-color-[0-9a-z]+/g;

wysihtml5.commands.foreColor = {
exec: function(composer, command, color) {
wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", "wysiwyg-color-" + color, REG_EXP);
wysihtml5.commands.formatInline.exec(composer, command, {className: "wysiwyg-color-" + color, classRegExp: REG_EXP, toggle: true});
},

state: function(composer, command, color) {
return wysihtml5.commands.formatInline.state(composer, command, "span", "wysiwyg-color-" + color, REG_EXP);
return wysihtml5.commands.formatInline.state(composer, command, {className: "wysiwyg-color-" + color});
}
};
})(wysihtml5);
Loading

0 comments on commit 34164ca

Please sign in to comment.