Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

scribe-plugin-curly-quotes

Package Overview
Dependencies
Maintainers
2
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

scribe-plugin-curly-quotes - npm Package Compare versions

Comparing version 0.1.2 to 0.1.4

.jshintrc

2

bower.json

@@ -5,4 +5,4 @@ {

"requirejs": "~2.1.9",
"scribe": "~0.1.10"
"scribe": "guardian/scribe#master"
}
}
{
"name": "scribe-plugin-curly-quotes",
"version": "0.1.2",
"version": "0.1.4",
"main": "src/scribe-plugin-curly-quotes.js",

@@ -16,3 +16,3 @@ "devDependencies": {

"selenium-webdriver": "~2.41.0",
"scribe-test-harness": "~0.0.1"
"scribe-test-harness": "~0.0.6"
},

@@ -19,0 +19,0 @@ "scripts": {

@@ -23,5 +23,11 @@ /*

glob('src/scribe-plugin-curly-quotes.js'),
requireJS(),
requireJS({
// FIXME: auto?
preserveLicenseComments: false,
paths: {
'lodash-amd': '../bower_components/lodash-amd',
}
}),
writeBoth
];
};

@@ -1,2 +0,2 @@

define(function () {
define([], function () {

@@ -7,7 +7,2 @@ 'use strict';

var keys = {
34: '"',
39: '\''
};
var openDoubleCurly = '“';

@@ -22,56 +17,38 @@ var closeDoubleCurly = '”';

return function (scribe) {
// Substitute quotes while typing
scribe.el.addEventListener('keypress', input);
/**
* Run the formatter as you type on the current paragraph.
*
* FIXME: We wouldn't have to do this if the formatters were run on text
* node mutations, but that's expensive unil we have a virtual DOM.
*/
// Substitute quotes on setting content or paste
scribe.registerHTMLFormatter('normalize', substituteCurlyQuotes);
var keys = {
34: '"',
39: '\''
};
var curlyQuoteChar;
function input(event) {
var curlyChar;
// `input` doesn't tell us what key was pressed, so we grab it beforehand
scribe.el.addEventListener('keypress', function (event) {
curlyQuoteChar = keys[event.charCode];
});
// If previous char is real content, close quote; else, open
// TODO: annoying Chrome/Firefox
var currentChar = keys[event.charCode];
if (currentChar === '"') {
if (wordBeforeSelectedRange()) {
curlyChar = closeDoubleCurly;
} else {
curlyChar = openDoubleCurly;
}
} else if (currentChar === '\'') {
if (wordBeforeSelectedRange()) {
curlyChar = closeSingleCurly;
} else {
curlyChar = openSingleCurly;
}
}
// Substitute entered char with curly replacement
if (curlyChar) {
event.preventDefault();
scribe.transactionManager.run(function() {
var quoteText = replaceSelectedRangeWith(curlyChar);
placeCaretAfter(quoteText);
// When the character is actually inserted, format it to transform.
scribe.el.addEventListener('input', function (event) {
if (curlyQuoteChar) {
var selection = new scribe.api.Selection();
var pElement = selection.getContaining(function (node) {
return node.nodeName === 'P';
});
selection.placeMarkers();
pElement.innerHTML = substituteCurlyQuotes(pElement.innerHTML);
selection.selectMarkers();
// Reset
curlyQuoteChar = undefined;
}
}
});
function wordBeforeSelectedRange() {
var prevChar = charBeforeSelectedRange() || '';
return isWordCharacter(prevChar);
}
// Substitute quotes on setting content or paste
scribe.registerHTMLFormatter('normalize', substituteCurlyQuotes);
function charBeforeSelectedRange() {
var selection = new scribe.api.Selection();
var context = selection.range.commonAncestorContainer.textContent;
return context[selection.range.startOffset - 1];
}
function charAfterSelectedRange() {
var selection = new scribe.api.Selection();
var context = selection.range.commonAncestorContainer.textContent;
return context[selection.range.endOffset];
}
function isWordCharacter(character) {

@@ -81,23 +58,2 @@ return /[^\s()]/.test(character);

/** Delete any selected text, insert text instead */
function replaceSelectedRangeWith(text) {
var textNode = document.createTextNode(text);
var selection = new scribe.api.Selection();
selection.range.deleteContents();
selection.range.insertNode(textNode);
return textNode;
}
function placeCaretAfter(node) {
var rangeAfter = document.createRange();
rangeAfter.setStartAfter(node);
rangeAfter.setEndAfter(node);
var selection = new scribe.api.Selection();
selection.selection.removeAllRanges();
selection.selection.addRange(rangeAfter);
}
function substituteCurlyQuotes(html) {

@@ -104,0 +60,0 @@ // We don't want to replace quotes within the HTML markup

@@ -9,4 +9,5 @@ var chai = require('chai');

var given = helpers.given;
var initializeScribe = helpers.initializeScribe.bind(null, 'scribe');
var initializeScribe = helpers.initializeScribe.bind(null, '../../bower_components/scribe/src/scribe');
var seleniumBugs = helpers.seleniumBugs;
var givenContentOf = helpers.givenContentOf;
var browserName = helpers.browserName;

@@ -51,3 +52,3 @@

// Firefox (23, 24, 25): '<p>“””<br></p>'
expect(innerHTML).to.have.html('<p>“<bogus-br></p>');
expect(innerHTML).to.have.html('<p>“<firefox-bogus-br></p>');
});

@@ -184,3 +185,3 @@ });

return driver.executeScript(function () {
window.scribe.insertHTML("<p>Hello 'world'!</p>");
window.scribe.insertHTML('<p>Hello \'world\'!</p>');
});

@@ -199,3 +200,3 @@ });

return driver.executeScript(function () {
window.scribe.insertHTML("<p>'Hello world!'</p>");
window.scribe.insertHTML('<p>\'Hello world!\'</p>');
});

@@ -215,3 +216,3 @@ });

// Misplaced inline elements wrt whitespace, but can happen
window.scribe.insertHTML("<p>'<em>Hello world!</em>' <strong>And </strong>'other'<strong> example</strong></p>");
window.scribe.insertHTML('<p>\'<em>Hello world!</em>\' <strong>And </strong>\'other\'<strong> example</strong></p>');
});

@@ -230,3 +231,3 @@ });

return driver.executeScript(function () {
window.scribe.insertHTML("<p>1\n'<em>2</em>'\n3</p>");
window.scribe.insertHTML('<p>1\n\'<em>2</em>\'\n3</p>');
});

@@ -237,3 +238,3 @@ });

return scribeNode.getInnerHTML().then(function (innerHTML) {
expect(innerHTML).to.equal("<p>1\n‘<em>2</em>’\n3</p>");
expect(innerHTML).to.equal('<p>1\n‘<em>2</em>’\n3</p>');
});

@@ -247,3 +248,3 @@ });

// Misplaced inline elements wrt whitespace, but can happen
window.scribe.insertHTML("<p>'<em>Hello world!</em>'</p>");
window.scribe.insertHTML('<p>\'<em>Hello world!</em>\'</p>');
});

@@ -265,3 +266,3 @@ });

return driver.executeScript(function () {
window.scribe.insertHTML("<p><em class='foo'>Just text</em></p>");
window.scribe.insertHTML('<p><em class=\'foo\'>Just text</em></p>');
});

@@ -281,3 +282,3 @@ });

return driver.executeScript(function () {
window.scribe.insertHTML("<p>&lt;p class='foo'&gt;1&lt;/p&gt;</p>");
window.scribe.insertHTML('<p>&lt;p class=\'foo\'&gt;1&lt;/p&gt;</p>');
});

@@ -288,3 +289,3 @@ });

return scribeNode.getInnerHTML().then(function (innerHTML) {
expect(innerHTML).to.equal("<p>&lt;p class='foo'&gt;1&lt;/p&gt;</p>");
expect(innerHTML).to.equal('<p>&lt;p class=\'foo\'&gt;1&lt;/p&gt;</p>');
});

@@ -399,2 +400,44 @@ });

});
givenContentOf('&lt;|&gt;', function () {
when('the user types an ascii single quote', function () {
beforeEach(function () {
return scribeNode.sendKeys('\'');
});
it('should not convert to a curly single quote', function () {
return scribeNode.getInnerHTML().then(function (innerHTML) {
expect(innerHTML).to.have.html('<p>&lt;\'&gt;</p>');
});
});
});
});
givenContentOf('&lt;|&gt;', function () {
when('the user types an ascii double quote', function () {
beforeEach(function () {
return scribeNode.sendKeys('"');
});
it('should not convert to a curly double quote', function () {
return scribeNode.getInnerHTML().then(function (innerHTML) {
expect(innerHTML).to.have.html('<p>&lt;"&gt;</p>');
});
});
});
});
givenContentOf('&lt;foo|&gt;', function () {
when('the user types content containing ascii single quotes (e.g. HTML attributes)', function () {
beforeEach(function () {
return scribeNode.sendKeys(' bar=\'baz\'');
});
it('should not convert to curly single quotes', function () {
return scribeNode.getInnerHTML().then(function (innerHTML) {
expect(innerHTML).to.have.html('<p>&lt;foo bar=\'baz\'&gt;</p>');
});
});
});
});
});

@@ -7,7 +7,5 @@ var Mocha = require('mocha');

/**
* FIXME: We have to set a ridiculous timeout (20 minutes) because Travis’
* concurrent builds will sometimes exceed Sauce Labs’ concurrency. We should
* track the following issue to add an option to Travis for limiting
* concurrency: https://github.com/travis-ci/travis-ci/issues/1366
* Wait for the connection to Sauce Labs to finish.
*/
mocha.timeout(15 * 1000);
mocha.timeout(1200000);

@@ -14,0 +12,0 @@ mocha.reporter('spec');

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc